| @@ -30,6 +30,7 @@ | |||||
| 844BB95D10C5579B00DF5536 /* juce_FillType.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F29A9E10C2EFA5005014DF /* juce_FillType.h */; }; | 844BB95D10C5579B00DF5536 /* juce_FillType.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F29A9E10C2EFA5005014DF /* juce_FillType.h */; }; | ||||
| 844BB95E10C557A600DF5536 /* juce_mac_CoreGraphicsContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84D0F00B109B1546007F73A3 /* juce_mac_CoreGraphicsContext.mm */; }; | 844BB95E10C557A600DF5536 /* juce_mac_CoreGraphicsContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84D0F00B109B1546007F73A3 /* juce_mac_CoreGraphicsContext.mm */; }; | ||||
| 844BB95F10C557A800DF5536 /* juce_Config.h in Headers */ = {isa = PBXBuildFile; fileRef = 8456EC6508A2A6C80087C412 /* juce_Config.h */; }; | 844BB95F10C557A800DF5536 /* juce_Config.h in Headers */ = {isa = PBXBuildFile; fileRef = 8456EC6508A2A6C80087C412 /* juce_Config.h */; }; | ||||
| 8458B536113ECFCF0044DA09 /* juce_ListenerList.h in Headers */ = {isa = PBXBuildFile; fileRef = 8458B535113ECFCF0044DA09 /* juce_ListenerList.h */; }; | |||||
| 8473E64A11249FD800D74E02 /* juce_TextInputTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 8473E64911249FD800D74E02 /* juce_TextInputTarget.h */; }; | 8473E64A11249FD800D74E02 /* juce_TextInputTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 8473E64911249FD800D74E02 /* juce_TextInputTarget.h */; }; | ||||
| 8473E64B11249FD800D74E02 /* juce_TextInputTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 8473E64911249FD800D74E02 /* juce_TextInputTarget.h */; }; | 8473E64B11249FD800D74E02 /* juce_TextInputTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 8473E64911249FD800D74E02 /* juce_TextInputTarget.h */; }; | ||||
| 8473E6531125974600D74E02 /* juce_Range.h in Headers */ = {isa = PBXBuildFile; fileRef = 8473E6521125974600D74E02 /* juce_Range.h */; }; | 8473E6531125974600D74E02 /* juce_Range.h in Headers */ = {isa = PBXBuildFile; fileRef = 8473E6521125974600D74E02 /* juce_Range.h */; }; | ||||
| @@ -1245,6 +1246,7 @@ | |||||
| 843D4A3A10D3C54500624BA6 /* juce_ValueTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = juce_ValueTree.h; sourceTree = "<group>"; }; | 843D4A3A10D3C54500624BA6 /* juce_ValueTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = juce_ValueTree.h; sourceTree = "<group>"; }; | ||||
| 8456EC6508A2A6C80087C412 /* juce_Config.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; lineEnding = 2; name = juce_Config.h; path = ../../juce_Config.h; sourceTree = SOURCE_ROOT; }; | 8456EC6508A2A6C80087C412 /* juce_Config.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; lineEnding = 2; name = juce_Config.h; path = ../../juce_Config.h; sourceTree = SOURCE_ROOT; }; | ||||
| 8456EC6908A2A6F00087C412 /* JUCE changelist.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = "JUCE changelist.txt"; path = "../../docs/JUCE changelist.txt"; sourceTree = SOURCE_ROOT; }; | 8456EC6908A2A6F00087C412 /* JUCE changelist.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = "JUCE changelist.txt"; path = "../../docs/JUCE changelist.txt"; sourceTree = SOURCE_ROOT; }; | ||||
| 8458B535113ECFCF0044DA09 /* juce_ListenerList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = juce_ListenerList.h; sourceTree = "<group>"; }; | |||||
| 8473E64911249FD800D74E02 /* juce_TextInputTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = juce_TextInputTarget.h; sourceTree = "<group>"; }; | 8473E64911249FD800D74E02 /* juce_TextInputTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = juce_TextInputTarget.h; sourceTree = "<group>"; }; | ||||
| 8473E6521125974600D74E02 /* juce_Range.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = juce_Range.h; sourceTree = "<group>"; }; | 8473E6521125974600D74E02 /* juce_Range.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = juce_Range.h; sourceTree = "<group>"; }; | ||||
| 84751E591132EE9E00640F9A /* juce_MouseInputSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = juce_MouseInputSource.cpp; sourceTree = "<group>"; }; | 84751E591132EE9E00640F9A /* juce_MouseInputSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = juce_MouseInputSource.cpp; sourceTree = "<group>"; }; | ||||
| @@ -2313,6 +2315,7 @@ | |||||
| 84F1E958104036B3006A1807 /* juce_InterprocessConnection.h */, | 84F1E958104036B3006A1807 /* juce_InterprocessConnection.h */, | ||||
| 84F1E959104036B3006A1807 /* juce_InterprocessConnectionServer.cpp */, | 84F1E959104036B3006A1807 /* juce_InterprocessConnectionServer.cpp */, | ||||
| 84F1E95A104036B3006A1807 /* juce_InterprocessConnectionServer.h */, | 84F1E95A104036B3006A1807 /* juce_InterprocessConnectionServer.h */, | ||||
| 8458B535113ECFCF0044DA09 /* juce_ListenerList.h */, | |||||
| 84F1E95B104036B3006A1807 /* juce_Message.cpp */, | 84F1E95B104036B3006A1807 /* juce_Message.cpp */, | ||||
| 84F1E95C104036B3006A1807 /* juce_Message.h */, | 84F1E95C104036B3006A1807 /* juce_Message.h */, | ||||
| 84F1E95D104036B3006A1807 /* juce_MessageListener.cpp */, | 84F1E95D104036B3006A1807 /* juce_MessageListener.cpp */, | ||||
| @@ -3594,6 +3597,7 @@ | |||||
| 8473E64A11249FD800D74E02 /* juce_TextInputTarget.h in Headers */, | 8473E64A11249FD800D74E02 /* juce_TextInputTarget.h in Headers */, | ||||
| 8473E6531125974600D74E02 /* juce_Range.h in Headers */, | 8473E6531125974600D74E02 /* juce_Range.h in Headers */, | ||||
| 84751E5C1132EE9E00640F9A /* juce_MouseInputSource.h in Headers */, | 84751E5C1132EE9E00640F9A /* juce_MouseInputSource.h in Headers */, | ||||
| 8458B536113ECFCF0044DA09 /* juce_ListenerList.h in Headers */, | |||||
| ); | ); | ||||
| runOnlyForDeploymentPostprocessing = 0; | runOnlyForDeploymentPostprocessing = 0; | ||||
| }; | }; | ||||
| @@ -1285,6 +1285,10 @@ | |||||
| RelativePath="..\..\..\src\events\juce_InterprocessConnectionServer.h" | RelativePath="..\..\..\src\events\juce_InterprocessConnectionServer.h" | ||||
| > | > | ||||
| </File> | </File> | ||||
| <File | |||||
| RelativePath="..\..\..\src\events\juce_ListenerList.h" | |||||
| > | |||||
| </File> | |||||
| <File | <File | ||||
| RelativePath="..\..\..\src\events\juce_Message.cpp" | RelativePath="..\..\..\src\events\juce_Message.cpp" | ||||
| > | > | ||||
| @@ -43,7 +43,7 @@ | |||||
| #define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
| #define JUCE_MINOR_VERSION 51 | #define JUCE_MINOR_VERSION 51 | ||||
| #define JUCE_BUILDNUMBER 6 | |||||
| #define JUCE_BUILDNUMBER 7 | |||||
| #define JUCE_VERSION ((JUCE_MAJOR_VERSION << 16) + (JUCE_MINOR_VERSION << 8) + JUCE_BUILDNUMBER) | #define JUCE_VERSION ((JUCE_MAJOR_VERSION << 16) + (JUCE_MINOR_VERSION << 8) + JUCE_BUILDNUMBER) | ||||
| @@ -1278,7 +1278,11 @@ public: | |||||
| void vprintf (const tchar* const format, va_list& args) throw(); | void vprintf (const tchar* const format, va_list& args) throw(); | ||||
| static const String repeatedString (const tchar* const stringToRepeat, | static const String repeatedString (const tchar* const stringToRepeat, | ||||
| int numberOfTimesToRepeat) throw(); | |||||
| int numberOfTimesToRepeat); | |||||
| const String paddedLeft (const juce_wchar padCharacter, int minimumLength) const; | |||||
| const String paddedRight (const juce_wchar padCharacter, int minimumLength) const; | |||||
| static const String createStringFromData (const void* const data, | static const String createStringFromData (const void* const data, | ||||
| const int size) throw(); | const int size) throw(); | ||||
| @@ -6013,6 +6017,211 @@ private: | |||||
| #endif // __JUCE_ASYNCUPDATER_JUCEHEADER__ | #endif // __JUCE_ASYNCUPDATER_JUCEHEADER__ | ||||
| /*** End of inlined file: juce_AsyncUpdater.h ***/ | /*** End of inlined file: juce_AsyncUpdater.h ***/ | ||||
| /*** Start of inlined file: juce_ListenerList.h ***/ | |||||
| #ifndef __JUCE_LISTENERLIST_JUCEHEADER__ | |||||
| #define __JUCE_LISTENERLIST_JUCEHEADER__ | |||||
| template <class ListenerClass, | |||||
| class ArrayType = Array <ListenerClass*> > | |||||
| class ListenerList | |||||
| { | |||||
| public: | |||||
| ListenerList() | |||||
| { | |||||
| } | |||||
| ~ListenerList() | |||||
| { | |||||
| } | |||||
| void add (ListenerClass* const listenerToAdd) | |||||
| { | |||||
| // Listeners can't be null pointers! | |||||
| jassert (listenerToAdd != 0); | |||||
| if (listenerToAdd != 0) | |||||
| listeners.add (listenerToAdd); | |||||
| } | |||||
| void remove (ListenerClass* const listenerToRemove) | |||||
| { | |||||
| // Listeners can't be null pointers! | |||||
| jassert (listenerToRemove != 0); | |||||
| listeners.removeValue (listenerToRemove); | |||||
| } | |||||
| int size() const throw() | |||||
| { | |||||
| return listeners.size(); | |||||
| } | |||||
| bool isEmpty() const throw() | |||||
| { | |||||
| return listeners.size() == 0; | |||||
| } | |||||
| bool contains (ListenerClass* const listener) const throw() | |||||
| { | |||||
| return listeners.contains (listener); | |||||
| } | |||||
| void call (void (ListenerClass::*callbackFunction) ()) | |||||
| { | |||||
| callChecked (DummyBailOutChecker(), callbackFunction); | |||||
| } | |||||
| template <class BailOutCheckerType> | |||||
| void callChecked (const BailOutCheckerType& bailOutChecker, | |||||
| void (ListenerClass::*callbackFunction) ()) | |||||
| { | |||||
| for (Iterator<BailOutCheckerType> iter (*this, bailOutChecker); iter.next();) | |||||
| (iter.getListener()->*callbackFunction) (); | |||||
| } | |||||
| template <typename P1, typename P2> | |||||
| void call (void (ListenerClass::*callbackFunction) (P1), | |||||
| P2& param1) | |||||
| { | |||||
| for (Iterator<DummyBailOutChecker> iter (*this, DummyBailOutChecker()); iter.next();) | |||||
| (iter.getListener()->*callbackFunction) (param1); | |||||
| } | |||||
| template <class BailOutCheckerType, typename P1, typename P2> | |||||
| void callChecked (const BailOutCheckerType& bailOutChecker, | |||||
| void (ListenerClass::*callbackFunction) (P1), | |||||
| P2& param1) | |||||
| { | |||||
| for (Iterator<BailOutCheckerType> iter (*this, bailOutChecker); iter.next();) | |||||
| (iter.getListener()->*callbackFunction) (param1); | |||||
| } | |||||
| template <typename P1, typename P2, typename P3, typename P4> | |||||
| void call (void (ListenerClass::*callbackFunction) (P1, P2), | |||||
| P3& param1, P4& param2) | |||||
| { | |||||
| for (Iterator<DummyBailOutChecker> iter (*this, DummyBailOutChecker()); iter.next();) | |||||
| (iter.getListener()->*callbackFunction) (param1, param2); | |||||
| } | |||||
| template <class BailOutCheckerType, typename P1, typename P2, typename P3, typename P4> | |||||
| void callChecked (const BailOutCheckerType& bailOutChecker, | |||||
| void (ListenerClass::*callbackFunction) (P1, P2), | |||||
| P3& param1, P4& param2) | |||||
| { | |||||
| for (Iterator<BailOutCheckerType> iter (*this, bailOutChecker); iter.next();) | |||||
| (iter.getListener()->*callbackFunction) (param1, param2); | |||||
| } | |||||
| template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6> | |||||
| void call (void (ListenerClass::*callbackFunction) (P1, P2, P3), | |||||
| P4& param1, P5& param2, P6& param3) | |||||
| { | |||||
| for (Iterator<DummyBailOutChecker> iter (*this, DummyBailOutChecker()); iter.next();) | |||||
| (iter.getListener()->*callbackFunction) (param1, param2, param3); | |||||
| } | |||||
| template <class BailOutCheckerType, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6> | |||||
| void callChecked (const BailOutCheckerType& bailOutChecker, | |||||
| void (ListenerClass::*callbackFunction) (P1, P2, P3), | |||||
| P4& param1, P5& param2, P6& param3) | |||||
| { | |||||
| for (Iterator<BailOutCheckerType> iter (*this, bailOutChecker); iter.next();) | |||||
| (iter.getListener()->*callbackFunction) (param1, param2, param3); | |||||
| } | |||||
| template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8> | |||||
| void call (void (ListenerClass::*callbackFunction) (P1, P2, P3, P4), | |||||
| P5& param1, P6& param2, P7& param3, P8& param4) | |||||
| { | |||||
| for (Iterator<DummyBailOutChecker> iter (*this, DummyBailOutChecker()); iter.next();) | |||||
| (iter.getListener()->*callbackFunction) (param1, param2, param3, param4); | |||||
| } | |||||
| template <class BailOutCheckerType, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8> | |||||
| void callChecked (const BailOutCheckerType& bailOutChecker, | |||||
| void (ListenerClass::*callbackFunction) (P1, P2, P3, P4), | |||||
| P5& param1, P6& param2, P7& param3, P8& param4) | |||||
| { | |||||
| for (Iterator<BailOutCheckerType> iter (*this, bailOutChecker); iter.next();) | |||||
| (iter.getListener()->*callbackFunction) (param1, param2, param3, param4); | |||||
| } | |||||
| template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10> | |||||
| void call (void (ListenerClass::*callbackFunction) (P1, P2, P3, P4, P5), | |||||
| P6& param1, P7& param2, P8& param3, P9& param4, P10& param5) | |||||
| { | |||||
| for (Iterator<DummyBailOutChecker> iter (*this, DummyBailOutChecker()); iter.next();) | |||||
| (iter.getListener()->*callbackFunction) (param1, param2, param3, param4, param5); | |||||
| } | |||||
| template <class BailOutCheckerType, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10> | |||||
| void callChecked (const BailOutCheckerType& bailOutChecker, | |||||
| void (ListenerClass::*callbackFunction) (P1, P2, P3, P4, P5), | |||||
| P6& param1, P7& param2, P8& param3, P9& param4, P10& param5) | |||||
| { | |||||
| for (Iterator<BailOutCheckerType> iter (*this, bailOutChecker); iter.next();) | |||||
| (iter.getListener()->*callbackFunction) (param1, param2, param3, param4, param5); | |||||
| } | |||||
| class DummyBailOutChecker | |||||
| { | |||||
| public: | |||||
| inline bool shouldBailOut() const throw() { return false; } | |||||
| }; | |||||
| template <class BailOutCheckerType> | |||||
| class Iterator | |||||
| { | |||||
| public: | |||||
| Iterator (const ListenerList& list_, const BailOutCheckerType& bailOutChecker_) | |||||
| : list (list_), bailOutChecker (bailOutChecker_), index (list_.size()) | |||||
| {} | |||||
| ~Iterator() {} | |||||
| bool next() | |||||
| { | |||||
| if (index <= 0 || bailOutChecker.shouldBailOut()) | |||||
| return false; | |||||
| const int listSize = list.size(); | |||||
| if (--index < listSize) | |||||
| return true; | |||||
| index = listSize - 1; | |||||
| return index >= 0; | |||||
| } | |||||
| ListenerClass* getListener() const throw() | |||||
| { | |||||
| return list.listeners.getUnchecked (index); | |||||
| } | |||||
| private: | |||||
| const ListenerList& list; | |||||
| const BailOutCheckerType& bailOutChecker; | |||||
| int index; | |||||
| Iterator (const Iterator&); | |||||
| Iterator& operator= (const Iterator&); | |||||
| }; | |||||
| private: | |||||
| ArrayType listeners; | |||||
| ListenerList (const ListenerList&); | |||||
| ListenerList& operator= (const ListenerList&); | |||||
| }; | |||||
| #endif // __JUCE_LISTENERLIST_JUCEHEADER__ | |||||
| /*** End of inlined file: juce_ListenerList.h ***/ | |||||
| class JUCE_API Value | class JUCE_API Value | ||||
| { | { | ||||
| public: | public: | ||||
| @@ -6088,7 +6297,7 @@ public: | |||||
| private: | private: | ||||
| friend class ValueSource; | friend class ValueSource; | ||||
| ReferenceCountedObjectPtr <ValueSource> value; | ReferenceCountedObjectPtr <ValueSource> value; | ||||
| SortedSet <Listener*> listeners; | |||||
| ListenerList <Listener> listeners; | |||||
| void callListeners(); | void callListeners(); | ||||
| @@ -6490,11 +6699,7 @@ private: | |||||
| typedef ReferenceCountedObjectPtr <SharedObject> SharedObjectPtr; | typedef ReferenceCountedObjectPtr <SharedObject> SharedObjectPtr; | ||||
| ReferenceCountedObjectPtr <SharedObject> object; | ReferenceCountedObjectPtr <SharedObject> object; | ||||
| SortedSet <Listener*> listeners; | |||||
| void deliverPropertyChangeMessage (ValueTree& tree, const var::identifier& property); | |||||
| void deliverChildChangeMessage (ValueTree& tree); | |||||
| void deliverParentChangeMessage (ValueTree& tree); | |||||
| ListenerList <Listener> listeners; | |||||
| ValueTree (SharedObject* const object_); | ValueTree (SharedObject* const object_); | ||||
| }; | }; | ||||
| @@ -9261,6 +9466,8 @@ public: | |||||
| int getDistanceFromDragStartY() const throw(); | int getDistanceFromDragStartY() const throw(); | ||||
| const Point<int> getOffsetFromDragStart() const throw(); | |||||
| bool mouseWasClicked() const throw(); | bool mouseWasClicked() const throw(); | ||||
| int getNumberOfClicks() const throw() { return numberOfClicks; } | int getNumberOfClicks() const throw() { return numberOfClicks; } | ||||
| @@ -12379,9 +12586,7 @@ public: | |||||
| return *this; | return *this; | ||||
| } | } | ||||
| operator ComponentType*() throw() { return comp; } | |||||
| operator const ComponentType*() const throw() { return comp; } | |||||
| operator ComponentType*() const throw() { return comp; } | |||||
| /** Returns the component that this pointer refers to, or null if the component no longer exists. */ | /** Returns the component that this pointer refers to, or null if the component no longer exists. */ | ||||
| ComponentType* operator->() throw() { jassert (comp != 0); return comp; } | ComponentType* operator->() throw() { jassert (comp != 0); return comp; } | ||||
| @@ -12399,6 +12604,22 @@ public: | |||||
| void componentBeingDeleted (Component&) { comp = 0; } | void componentBeingDeleted (Component&) { comp = 0; } | ||||
| }; | }; | ||||
| class BailOutChecker | |||||
| { | |||||
| public: | |||||
| BailOutChecker (Component* const component1, | |||||
| Component* const component2 = 0); | |||||
| bool shouldBailOut() const throw(); | |||||
| private: | |||||
| Component::SafePointer<Component> safePointer1, safePointer2; | |||||
| Component* const component2; | |||||
| BailOutChecker (const BailOutChecker&); | |||||
| BailOutChecker& operator= (const BailOutChecker&); | |||||
| }; | |||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| private: | private: | ||||
| @@ -12422,7 +12643,7 @@ private: | |||||
| Image* bufferedImage_; | Image* bufferedImage_; | ||||
| VoidArray* mouseListeners_; | VoidArray* mouseListeners_; | ||||
| VoidArray* keyListeners_; | VoidArray* keyListeners_; | ||||
| VoidArray* componentListeners_; | |||||
| ListenerList <ComponentListener> componentListeners; | |||||
| NamedValueSet properties; | NamedValueSet properties; | ||||
| struct ComponentFlags | struct ComponentFlags | ||||
| @@ -12876,13 +13097,13 @@ class JUCE_API Desktop : private DeletedAtShutdown, | |||||
| { | { | ||||
| public: | public: | ||||
| static Desktop& JUCE_CALLTYPE getInstance() throw(); | |||||
| static Desktop& JUCE_CALLTYPE getInstance(); | |||||
| const RectangleList getAllMonitorDisplayAreas (const bool clippedToWorkArea = true) const throw(); | const RectangleList getAllMonitorDisplayAreas (const bool clippedToWorkArea = true) const throw(); | ||||
| const Rectangle<int> getMainMonitorArea (const bool clippedToWorkArea = true) const throw(); | const Rectangle<int> getMainMonitorArea (const bool clippedToWorkArea = true) const throw(); | ||||
| const Rectangle<int> getMonitorAreaContaining (const Point<int>& position, const bool clippedToWorkArea = true) const throw(); | |||||
| const Rectangle<int> getMonitorAreaContaining (const Point<int>& position, const bool clippedToWorkArea = true) const; | |||||
| static const Point<int> getMousePosition(); | static const Point<int> getMousePosition(); | ||||
| @@ -12896,18 +13117,18 @@ public: | |||||
| static bool isScreenSaverEnabled() throw(); | static bool isScreenSaverEnabled() throw(); | ||||
| void addGlobalMouseListener (MouseListener* const listener) throw(); | |||||
| void addGlobalMouseListener (MouseListener* const listener); | |||||
| void removeGlobalMouseListener (MouseListener* const listener) throw(); | |||||
| void removeGlobalMouseListener (MouseListener* const listener); | |||||
| void addFocusChangeListener (FocusChangeListener* const listener) throw(); | |||||
| void addFocusChangeListener (FocusChangeListener* const listener); | |||||
| void removeFocusChangeListener (FocusChangeListener* const listener) throw(); | |||||
| void removeFocusChangeListener (FocusChangeListener* const listener); | |||||
| void setKioskModeComponent (Component* componentToUse, | void setKioskModeComponent (Component* componentToUse, | ||||
| const bool allowMenusAndBars = true); | const bool allowMenusAndBars = true); | ||||
| Component* getKioskModeComponent() const { return kioskModeComponent; } | |||||
| Component* getKioskModeComponent() const throw() { return kioskModeComponent; } | |||||
| int getNumComponents() const throw(); | int getNumComponents() const throw(); | ||||
| @@ -12927,7 +13148,7 @@ public: | |||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| void refreshMonitorSizes() throw(); | |||||
| void refreshMonitorSizes(); | |||||
| static bool canUseSemiTransparentWindows() throw(); | static bool canUseSemiTransparentWindows() throw(); | ||||
| @@ -12939,42 +13160,43 @@ private: | |||||
| friend class ComponentPeer; | friend class ComponentPeer; | ||||
| friend class MouseInputSource; | friend class MouseInputSource; | ||||
| friend class MouseInputSourceInternal; | friend class MouseInputSourceInternal; | ||||
| SortedSet <void*> mouseListeners, focusListeners; | |||||
| Array <Component*> desktopComponents; | |||||
| friend class DeletedAtShutdown; | friend class DeletedAtShutdown; | ||||
| friend class TopLevelWindowManager; | friend class TopLevelWindowManager; | ||||
| Desktop() throw(); | |||||
| ~Desktop() throw(); | |||||
| Array <Rectangle<int> > monitorCoordsClipped, monitorCoordsUnclipped; | |||||
| OwnedArray <MouseInputSource> mouseSources; | OwnedArray <MouseInputSource> mouseSources; | ||||
| void createMouseInputSources(); | |||||
| ListenerList <MouseListener> mouseListeners; | |||||
| ListenerList <FocusChangeListener> focusListeners; | |||||
| Array <Component*> desktopComponents; | |||||
| Array <Rectangle<int> > monitorCoordsClipped, monitorCoordsUnclipped; | |||||
| Point<int> lastFakeMouseMove; | Point<int> lastFakeMouseMove; | ||||
| int mouseClickCounter; | |||||
| void sendMouseMove(); | |||||
| int mouseClickCounter; | |||||
| void incrementMouseClickCounter() throw(); | void incrementMouseClickCounter() throw(); | ||||
| Component* kioskModeComponent; | Component* kioskModeComponent; | ||||
| Rectangle<int> kioskComponentOriginalBounds; | Rectangle<int> kioskComponentOriginalBounds; | ||||
| void createMouseInputSources(); | |||||
| void timerCallback(); | void timerCallback(); | ||||
| void sendMouseMove(); | |||||
| void resetTimer() throw(); | |||||
| void resetTimer(); | |||||
| int getNumDisplayMonitors() const throw(); | int getNumDisplayMonitors() const throw(); | ||||
| const Rectangle<int> getDisplayMonitorCoordinates (const int index, const bool clippedToWorkArea) const throw(); | const Rectangle<int> getDisplayMonitorCoordinates (const int index, const bool clippedToWorkArea) const throw(); | ||||
| void addDesktopComponent (Component* const c) throw(); | |||||
| void removeDesktopComponent (Component* const c) throw(); | |||||
| void componentBroughtToFront (Component* const c) throw(); | |||||
| void addDesktopComponent (Component* const c); | |||||
| void removeDesktopComponent (Component* const c); | |||||
| void componentBroughtToFront (Component* const c); | |||||
| void triggerFocusCallback() throw(); | |||||
| void triggerFocusCallback(); | |||||
| void handleAsyncUpdate(); | void handleAsyncUpdate(); | ||||
| Desktop(); | |||||
| ~Desktop(); | |||||
| Desktop (const Desktop&); | Desktop (const Desktop&); | ||||
| Desktop& operator= (const Desktop&); | Desktop& operator= (const Desktop&); | ||||
| }; | }; | ||||
| @@ -13046,11 +13268,11 @@ public: | |||||
| private: | private: | ||||
| OwnedArray <ApplicationCommandInfo> commands; | OwnedArray <ApplicationCommandInfo> commands; | ||||
| SortedSet <void*> listeners; | |||||
| ListenerList <ApplicationCommandManagerListener> listeners; | |||||
| ScopedPointer <KeyPressMappingSet> keyMappings; | ScopedPointer <KeyPressMappingSet> keyMappings; | ||||
| ApplicationCommandTarget* firstTarget; | ApplicationCommandTarget* firstTarget; | ||||
| void sendListenerInvokeCallback (const ApplicationCommandTarget::InvocationInfo& info) const; | |||||
| void sendListenerInvokeCallback (const ApplicationCommandTarget::InvocationInfo& info); | |||||
| void handleAsyncUpdate(); | void handleAsyncUpdate(); | ||||
| void globalFocusChanged (Component*); | void globalFocusChanged (Component*); | ||||
| @@ -15708,9 +15930,9 @@ protected: | |||||
| private: | private: | ||||
| Array <KeyPress> shortcuts; | Array <KeyPress> shortcuts; | ||||
| Component* keySource; | |||||
| Component::SafePointer<Component> keySource; | |||||
| String text; | String text; | ||||
| SortedSet <void*> buttonListeners; | |||||
| ListenerList <ButtonListener> buttonListeners; | |||||
| class RepeatTimer; | class RepeatTimer; | ||||
| friend class RepeatTimer; | friend class RepeatTimer; | ||||
| @@ -15843,7 +16065,7 @@ private: | |||||
| bool vertical, isDraggingThumb, alwaysVisible; | bool vertical, isDraggingThumb, alwaysVisible; | ||||
| Button* upButton; | Button* upButton; | ||||
| Button* downButton; | Button* downButton; | ||||
| SortedSet <void*> listeners; | |||||
| ListenerList <ScrollBarListener> listeners; | |||||
| void updateThumbPosition() throw(); | void updateThumbPosition() throw(); | ||||
| void timerCallback(); | void timerCallback(); | ||||
| @@ -15921,7 +16143,7 @@ public: | |||||
| bool useMouseWheelMoveIfNeeded (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY); | bool useMouseWheelMoveIfNeeded (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY); | ||||
| private: | private: | ||||
| Component* contentComp; | |||||
| Component::SafePointer<Component> contentComp; | |||||
| int lastVX, lastVY, lastVW, lastVH; | int lastVX, lastVY, lastVW, lastVH; | ||||
| int scrollBarThickness; | int scrollBarThickness; | ||||
| int singleStepX, singleStepY; | int singleStepX, singleStepY; | ||||
| @@ -16385,7 +16607,7 @@ private: | |||||
| } dragType; | } dragType; | ||||
| String allowedCharacters; | String allowedCharacters; | ||||
| SortedSet <void*> listeners; | |||||
| ListenerList <TextEditorListener> listeners; | |||||
| friend class TextEditorInsertAction; | friend class TextEditorInsertAction; | ||||
| friend class TextEditorRemoveAction; | friend class TextEditorRemoveAction; | ||||
| @@ -16562,7 +16784,7 @@ private: | |||||
| Font font; | Font font; | ||||
| Justification justification; | Justification justification; | ||||
| ScopedPointer <TextEditor> editor; | ScopedPointer <TextEditor> editor; | ||||
| SortedSet <void*> listeners; | |||||
| ListenerList <LabelListener> listeners; | |||||
| Component::SafePointer<Component> ownerComponent; | Component::SafePointer<Component> ownerComponent; | ||||
| int horizontalBorderSize, verticalBorderSize; | int horizontalBorderSize, verticalBorderSize; | ||||
| float minimumHorizontalScale; | float minimumHorizontalScale; | ||||
| @@ -16710,7 +16932,7 @@ private: | |||||
| Value currentId; | Value currentId; | ||||
| int lastCurrentId; | int lastCurrentId; | ||||
| bool isButtonDown, separatorPending, menuActive, textIsCustom; | bool isButtonDown, separatorPending, menuActive, textIsCustom; | ||||
| SortedSet <void*> listeners; | |||||
| ListenerList <ComboBoxListener> listeners; | |||||
| ScopedPointer<Label> label; | ScopedPointer<Label> label; | ||||
| String textWhenNothingSelected, noChoicesMessage; | String textWhenNothingSelected, noChoicesMessage; | ||||
| @@ -19335,6 +19557,9 @@ private: | |||||
| /*** End of inlined file: juce_InterprocessConnectionServer.h ***/ | /*** End of inlined file: juce_InterprocessConnectionServer.h ***/ | ||||
| #endif | |||||
| #ifndef __JUCE_LISTENERLIST_JUCEHEADER__ | |||||
| #endif | #endif | ||||
| #ifndef __JUCE_MESSAGE_JUCEHEADER__ | #ifndef __JUCE_MESSAGE_JUCEHEADER__ | ||||
| @@ -21063,7 +21288,7 @@ protected: | |||||
| void valueChanged (Value& value); | void valueChanged (Value& value); | ||||
| private: | private: | ||||
| SortedSet <void*> listeners; | |||||
| ListenerList <SliderListener> listeners; | |||||
| Value currentValue, valueMin, valueMax; | Value currentValue, valueMin, valueMax; | ||||
| double lastCurrentValue, lastValueMin, lastValueMax; | double lastCurrentValue, lastValueMin, lastValueMax; | ||||
| double minimum, maximum, interval, doubleClickReturnValue; | double minimum, maximum, interval, doubleClickReturnValue; | ||||
| @@ -22067,7 +22292,7 @@ public: | |||||
| protected: | protected: | ||||
| DirectoryContentsList& fileList; | DirectoryContentsList& fileList; | ||||
| SortedSet <void*> listeners; | |||||
| ListenerList <FileBrowserListener> listeners; | |||||
| DirectoryContentsDisplayComponent (const DirectoryContentsDisplayComponent&); | DirectoryContentsDisplayComponent (const DirectoryContentsDisplayComponent&); | ||||
| DirectoryContentsDisplayComponent& operator= (const DirectoryContentsDisplayComponent&); | DirectoryContentsDisplayComponent& operator= (const DirectoryContentsDisplayComponent&); | ||||
| @@ -22197,7 +22422,7 @@ private: | |||||
| int flags; | int flags; | ||||
| File currentRoot; | File currentRoot; | ||||
| Array<File> chosenFiles; | Array<File> chosenFiles; | ||||
| SortedSet <void*> listeners; | |||||
| ListenerList <FileBrowserListener> listeners; | |||||
| DirectoryContentsDisplayComponent* fileListComponent; | DirectoryContentsDisplayComponent* fileListComponent; | ||||
| FilePreviewComponent* previewComp; | FilePreviewComponent* previewComp; | ||||
| @@ -22537,9 +22762,9 @@ public: | |||||
| ~ResizableBorderComponent(); | ~ResizableBorderComponent(); | ||||
| void setBorderThickness (const BorderSize& newBorderSize) throw(); | |||||
| void setBorderThickness (const BorderSize& newBorderSize); | |||||
| const BorderSize getBorderThickness() const throw(); | |||||
| const BorderSize getBorderThickness() const; | |||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| @@ -22553,13 +22778,13 @@ protected: | |||||
| bool hitTest (int x, int y); | bool hitTest (int x, int y); | ||||
| private: | private: | ||||
| Component* const component; | |||||
| Component::SafePointer<Component> component; | |||||
| ComponentBoundsConstrainer* constrainer; | ComponentBoundsConstrainer* constrainer; | ||||
| BorderSize borderSize; | BorderSize borderSize; | ||||
| int originalX, originalY, originalW, originalH; | |||||
| Rectangle<int> originalBounds; | |||||
| int mouseZone; | int mouseZone; | ||||
| void updateMouseZone (const MouseEvent& e) throw(); | |||||
| void updateMouseZone (const MouseEvent& e); | |||||
| ResizableBorderComponent (const ResizableBorderComponent&); | ResizableBorderComponent (const ResizableBorderComponent&); | ||||
| ResizableBorderComponent& operator= (const ResizableBorderComponent&); | ResizableBorderComponent& operator= (const ResizableBorderComponent&); | ||||
| @@ -22593,9 +22818,9 @@ protected: | |||||
| private: | private: | ||||
| Component* const component; | |||||
| Component::SafePointer<Component> component; | |||||
| ComponentBoundsConstrainer* constrainer; | ComponentBoundsConstrainer* constrainer; | ||||
| int originalX, originalY, originalW, originalH; | |||||
| Rectangle<int> originalBounds; | |||||
| ResizableCornerComponent (const ResizableCornerComponent&); | ResizableCornerComponent (const ResizableCornerComponent&); | ||||
| ResizableCornerComponent& operator= (const ResizableCornerComponent&); | ResizableCornerComponent& operator= (const ResizableCornerComponent&); | ||||
| @@ -23038,7 +23263,7 @@ private: | |||||
| int maxRecentFiles; | int maxRecentFiles; | ||||
| bool isDir, isSaving, isFileDragOver; | bool isDir, isSaving, isFileDragOver; | ||||
| String wildcard, enforcedSuffix, browseButtonText; | String wildcard, enforcedSuffix, browseButtonText; | ||||
| SortedSet <void*> listeners; | |||||
| ListenerList <FilenameComponentListener> listeners; | |||||
| File defaultBrowseFile; | File defaultBrowseFile; | ||||
| void comboBoxChanged (ComboBox*); | void comboBoxChanged (ComboBox*); | ||||
| @@ -23853,7 +24078,7 @@ public: | |||||
| private: | private: | ||||
| ApplicationCommandManager* manager; | ApplicationCommandManager* manager; | ||||
| SortedSet <void*> listeners; | |||||
| ListenerList <MenuBarModelListener> listeners; | |||||
| MenuBarModel (const MenuBarModel&); | MenuBarModel (const MenuBarModel&); | ||||
| MenuBarModel& operator= (const MenuBarModel&); | MenuBarModel& operator= (const MenuBarModel&); | ||||
| @@ -25516,6 +25741,81 @@ private: | |||||
| /*** End of inlined file: juce_MouseHoverDetector.h ***/ | /*** End of inlined file: juce_MouseHoverDetector.h ***/ | ||||
| #endif | |||||
| #ifndef __JUCE_MOUSEINPUTSOURCE_JUCEHEADER__ | |||||
| /*** Start of inlined file: juce_MouseInputSource.h ***/ | |||||
| #ifndef __JUCE_MOUSEINPUTSOURCE_JUCEHEADER__ | |||||
| #define __JUCE_MOUSEINPUTSOURCE_JUCEHEADER__ | |||||
| class Component; | |||||
| class ComponentPeer; | |||||
| class MouseInputSourceInternal; | |||||
| class JUCE_API MouseInputSource | |||||
| { | |||||
| public: | |||||
| MouseInputSource (int index, bool isMouseDevice); | |||||
| ~MouseInputSource(); | |||||
| bool isMouse() const; | |||||
| bool isTouch() const; | |||||
| bool canHover() const; | |||||
| bool hasMouseWheel() const; | |||||
| int getIndex() const; | |||||
| bool isDragging() const; | |||||
| const Point<int> getScreenPosition() const; | |||||
| const ModifierKeys getCurrentModifiers() const; | |||||
| Component* getComponentUnderMouse() const; | |||||
| void triggerFakeMove() const; | |||||
| int getNumberOfMultipleClicks() const throw(); | |||||
| const Time getLastMouseDownTime() const throw(); | |||||
| const Point<int> getLastMouseDownPosition() const throw(); | |||||
| bool hasMouseMovedSignificantlySincePressed() const throw(); | |||||
| bool hasMouseCursor() const throw(); | |||||
| void showMouseCursor (const MouseCursor& cursor); | |||||
| void hideCursor(); | |||||
| void revealCursor(); | |||||
| bool canDoUnboundedMovement() const throw(); | |||||
| void enableUnboundedMouseMovement (bool isEnabled, bool keepCursorVisibleUntilOffscreen = false); | |||||
| juce_UseDebuggingNewOperator | |||||
| void handleEvent (ComponentPeer* peer, const Point<int>& positionWithinPeer, int64 time, const ModifierKeys& mods); | |||||
| void handleWheel (ComponentPeer* peer, const Point<int>& positionWithinPeer, int64 time, float x, float y); | |||||
| private: | |||||
| friend class Desktop; | |||||
| friend class ComponentPeer; | |||||
| friend class MouseInputSourceInternal; | |||||
| ScopedPointer<MouseInputSourceInternal> pimpl; | |||||
| MouseInputSource (const MouseInputSource&); | |||||
| MouseInputSource& operator= (const MouseInputSource&); | |||||
| }; | |||||
| #endif // __JUCE_MOUSEINPUTSOURCE_JUCEHEADER__ | |||||
| /*** End of inlined file: juce_MouseInputSource.h ***/ | |||||
| #endif | #endif | ||||
| #ifndef __JUCE_MOUSELISTENER_JUCEHEADER__ | #ifndef __JUCE_MOUSELISTENER_JUCEHEADER__ | ||||
| @@ -26069,78 +26369,6 @@ private: | |||||
| #ifndef __JUCE_MAGNIFIERCOMPONENT_JUCEHEADER__ | #ifndef __JUCE_MAGNIFIERCOMPONENT_JUCEHEADER__ | ||||
| #define __JUCE_MAGNIFIERCOMPONENT_JUCEHEADER__ | #define __JUCE_MAGNIFIERCOMPONENT_JUCEHEADER__ | ||||
| /*** Start of inlined file: juce_MouseInputSource.h ***/ | |||||
| #ifndef __JUCE_MOUSEEVENT_JUCEHEADER__x | |||||
| #define __JUCE_MOUSEEVENT_JUCEHEADER__x | |||||
| class Component; | |||||
| class ComponentPeer; | |||||
| class MouseInputSourceInternal; | |||||
| class JUCE_API MouseInputSource | |||||
| { | |||||
| public: | |||||
| MouseInputSource (int index, bool isMouseDevice); | |||||
| ~MouseInputSource(); | |||||
| bool isMouse() const; | |||||
| bool isTouch() const; | |||||
| bool canHover() const; | |||||
| bool hasMouseWheel() const; | |||||
| int getIndex() const; | |||||
| bool isDragging() const; | |||||
| const Point<int> getScreenPosition() const; | |||||
| const ModifierKeys getCurrentModifiers() const; | |||||
| Component* getComponentUnderMouse() const; | |||||
| void triggerFakeMove() const; | |||||
| int getNumberOfMultipleClicks() const throw(); | |||||
| const Time getLastMouseDownTime() const throw(); | |||||
| const Point<int> getLastMouseDownPosition() const throw(); | |||||
| bool hasMouseMovedSignificantlySincePressed() const throw(); | |||||
| bool hasMouseCursor() const throw(); | |||||
| void showMouseCursor (const MouseCursor& cursor); | |||||
| void hideCursor(); | |||||
| void revealCursor(); | |||||
| bool canDoUnboundedMovement() const throw(); | |||||
| void enableUnboundedMouseMovement (bool isEnabled, bool keepCursorVisibleUntilOffscreen = false); | |||||
| juce_UseDebuggingNewOperator | |||||
| void handleEvent (ComponentPeer* peer, const Point<int>& positionWithinPeer, int64 time, const ModifierKeys& mods); | |||||
| void handleWheel (ComponentPeer* peer, const Point<int>& positionWithinPeer, int64 time, float x, float y); | |||||
| private: | |||||
| friend class Desktop; | |||||
| friend class ComponentPeer; | |||||
| friend class MouseInputSourceInternal; | |||||
| ScopedPointer<MouseInputSourceInternal> pimpl; | |||||
| MouseInputSource (const MouseInputSource&); | |||||
| MouseInputSource& operator= (const MouseInputSource&); | |||||
| }; | |||||
| #endif // __JUCE_MOUSEEVENT_JUCEHEADER__ | |||||
| /*** End of inlined file: juce_MouseInputSource.h ***/ | |||||
| class JUCE_API MagnifierComponent : public Component | class JUCE_API MagnifierComponent : public Component | ||||
| { | { | ||||
| public: | public: | ||||
| @@ -305,32 +305,22 @@ ApplicationCommandTarget* ApplicationCommandManager::findDefaultComponentTarget( | |||||
| //============================================================================== | //============================================================================== | ||||
| void ApplicationCommandManager::addListener (ApplicationCommandManagerListener* const listener) throw() | void ApplicationCommandManager::addListener (ApplicationCommandManagerListener* const listener) throw() | ||||
| { | { | ||||
| jassert (listener != 0); | |||||
| if (listener != 0) | |||||
| listeners.add (listener); | |||||
| listeners.add (listener); | |||||
| } | } | ||||
| void ApplicationCommandManager::removeListener (ApplicationCommandManagerListener* const listener) throw() | void ApplicationCommandManager::removeListener (ApplicationCommandManagerListener* const listener) throw() | ||||
| { | { | ||||
| listeners.removeValue (listener); | |||||
| listeners.remove (listener); | |||||
| } | } | ||||
| void ApplicationCommandManager::sendListenerInvokeCallback (const ApplicationCommandTarget::InvocationInfo& info) const | |||||
| void ApplicationCommandManager::sendListenerInvokeCallback (const ApplicationCommandTarget::InvocationInfo& info) | |||||
| { | { | ||||
| for (int i = listeners.size(); --i >= 0;) | |||||
| { | |||||
| ((ApplicationCommandManagerListener*) listeners.getUnchecked (i))->applicationCommandInvoked (info); | |||||
| i = jmin (i, listeners.size()); | |||||
| } | |||||
| listeners.call (&ApplicationCommandManagerListener::applicationCommandInvoked, info); | |||||
| } | } | ||||
| void ApplicationCommandManager::handleAsyncUpdate() | void ApplicationCommandManager::handleAsyncUpdate() | ||||
| { | { | ||||
| for (int i = listeners.size(); --i >= 0;) | |||||
| { | |||||
| ((ApplicationCommandManagerListener*) listeners.getUnchecked (i))->applicationCommandListChanged(); | |||||
| i = jmin (i, listeners.size()); | |||||
| } | |||||
| listeners.call (&ApplicationCommandManagerListener::applicationCommandListChanged); | |||||
| } | } | ||||
| void ApplicationCommandManager::globalFocusChanged (Component*) | void ApplicationCommandManager::globalFocusChanged (Component*) | ||||
| @@ -320,11 +320,11 @@ public: | |||||
| private: | private: | ||||
| //============================================================================== | //============================================================================== | ||||
| OwnedArray <ApplicationCommandInfo> commands; | OwnedArray <ApplicationCommandInfo> commands; | ||||
| SortedSet <void*> listeners; | |||||
| ListenerList <ApplicationCommandManagerListener> listeners; | |||||
| ScopedPointer <KeyPressMappingSet> keyMappings; | ScopedPointer <KeyPressMappingSet> keyMappings; | ||||
| ApplicationCommandTarget* firstTarget; | ApplicationCommandTarget* firstTarget; | ||||
| void sendListenerInvokeCallback (const ApplicationCommandTarget::InvocationInfo& info) const; | |||||
| void sendListenerInvokeCallback (const ApplicationCommandTarget::InvocationInfo& info); | |||||
| void handleAsyncUpdate(); | void handleAsyncUpdate(); | ||||
| void globalFocusChanged (Component*); | void globalFocusChanged (Component*); | ||||
| @@ -200,7 +200,7 @@ void Value::addListener (Listener* const listener) | |||||
| void Value::removeListener (Listener* const listener) | void Value::removeListener (Listener* const listener) | ||||
| { | { | ||||
| listeners.removeValue (listener); | |||||
| listeners.remove (listener); | |||||
| if (listeners.size() == 0) | if (listeners.size() == 0) | ||||
| value->valuesWithListeners.removeValue (this); | value->valuesWithListeners.removeValue (this); | ||||
| @@ -208,15 +208,9 @@ void Value::removeListener (Listener* const listener) | |||||
| void Value::callListeners() | void Value::callListeners() | ||||
| { | { | ||||
| Value valueCopy (*this); // Use a copy in case this object gets deleted by a callback | |||||
| for (int i = listeners.size(); --i >= 0;) | |||||
| { | |||||
| Listener* const l = listeners[i]; | |||||
| if (l != 0) | |||||
| l->valueChanged (valueCopy); | |||||
| } | |||||
| Value v (*this); // (create a copy in case this gets deleted by a callback) | |||||
| listeners.call (&Listener::valueChanged, v); | |||||
| } | } | ||||
| END_JUCE_NAMESPACE | END_JUCE_NAMESPACE | ||||
| @@ -28,6 +28,7 @@ | |||||
| #include "juce_Variant.h" | #include "juce_Variant.h" | ||||
| #include "../events/juce_AsyncUpdater.h" | #include "../events/juce_AsyncUpdater.h" | ||||
| #include "../events/juce_ListenerList.h" | |||||
| #include "juce_ReferenceCountedObject.h" | #include "juce_ReferenceCountedObject.h" | ||||
| #include "juce_SortedSet.h" | #include "juce_SortedSet.h" | ||||
| @@ -217,7 +218,7 @@ public: | |||||
| private: | private: | ||||
| friend class ValueSource; | friend class ValueSource; | ||||
| ReferenceCountedObjectPtr <ValueSource> value; | ReferenceCountedObjectPtr <ValueSource> value; | ||||
| SortedSet <Listener*> listeners; | |||||
| ListenerList <Listener> listeners; | |||||
| void callListeners(); | void callListeners(); | ||||
| @@ -162,23 +162,13 @@ ValueTree::SharedObject::~SharedObject() | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| void ValueTree::deliverPropertyChangeMessage (ValueTree& tree, const var::identifier& property) | |||||
| { | |||||
| for (int i = listeners.size(); --i >= 0;) | |||||
| { | |||||
| ValueTree::Listener* const l = listeners[i]; | |||||
| if (l != 0) | |||||
| l->valueTreePropertyChanged (tree, property); | |||||
| } | |||||
| } | |||||
| void ValueTree::SharedObject::sendPropertyChangeMessage (ValueTree& tree, const var::identifier& property) | void ValueTree::SharedObject::sendPropertyChangeMessage (ValueTree& tree, const var::identifier& property) | ||||
| { | { | ||||
| for (int i = valueTreesWithListeners.size(); --i >= 0;) | for (int i = valueTreesWithListeners.size(); --i >= 0;) | ||||
| { | { | ||||
| ValueTree* const v = valueTreesWithListeners[i]; | ValueTree* const v = valueTreesWithListeners[i]; | ||||
| if (v != 0) | if (v != 0) | ||||
| v->deliverPropertyChangeMessage (tree, property); | |||||
| v->listeners.call (&ValueTree::Listener::valueTreePropertyChanged, tree, property); | |||||
| } | } | ||||
| } | } | ||||
| @@ -194,23 +184,13 @@ void ValueTree::SharedObject::sendPropertyChangeMessage (const var::identifier& | |||||
| } | } | ||||
| } | } | ||||
| void ValueTree::deliverChildChangeMessage (ValueTree& tree) | |||||
| { | |||||
| for (int i = listeners.size(); --i >= 0;) | |||||
| { | |||||
| ValueTree::Listener* const l = listeners[i]; | |||||
| if (l != 0) | |||||
| l->valueTreeChildrenChanged (tree); | |||||
| } | |||||
| } | |||||
| void ValueTree::SharedObject::sendChildChangeMessage (ValueTree& tree) | void ValueTree::SharedObject::sendChildChangeMessage (ValueTree& tree) | ||||
| { | { | ||||
| for (int i = valueTreesWithListeners.size(); --i >= 0;) | for (int i = valueTreesWithListeners.size(); --i >= 0;) | ||||
| { | { | ||||
| ValueTree* const v = valueTreesWithListeners[i]; | ValueTree* const v = valueTreesWithListeners[i]; | ||||
| if (v != 0) | if (v != 0) | ||||
| v->deliverChildChangeMessage (tree); | |||||
| v->listeners.call (&ValueTree::Listener::valueTreeChildrenChanged, tree); | |||||
| } | } | ||||
| } | } | ||||
| @@ -226,16 +206,6 @@ void ValueTree::SharedObject::sendChildChangeMessage() | |||||
| } | } | ||||
| } | } | ||||
| void ValueTree::deliverParentChangeMessage (ValueTree& tree) | |||||
| { | |||||
| for (int i = listeners.size(); --i >= 0;) | |||||
| { | |||||
| ValueTree::Listener* const l = listeners[i]; | |||||
| if (l != 0) | |||||
| l->valueTreeParentChanged (tree); | |||||
| } | |||||
| } | |||||
| void ValueTree::SharedObject::sendParentChangeMessage() | void ValueTree::SharedObject::sendParentChangeMessage() | ||||
| { | { | ||||
| ValueTree tree (this); | ValueTree tree (this); | ||||
| @@ -252,7 +222,7 @@ void ValueTree::SharedObject::sendParentChangeMessage() | |||||
| { | { | ||||
| ValueTree* const v = valueTreesWithListeners[i]; | ValueTree* const v = valueTreesWithListeners[i]; | ||||
| if (v != 0) | if (v != 0) | ||||
| v->deliverParentChangeMessage (tree); | |||||
| v->listeners.call (&ValueTree::Listener::valueTreeParentChanged, tree); | |||||
| } | } | ||||
| } | } | ||||
| @@ -651,7 +621,7 @@ void ValueTree::addListener (Listener* listener) | |||||
| void ValueTree::removeListener (Listener* listener) | void ValueTree::removeListener (Listener* listener) | ||||
| { | { | ||||
| listeners.removeValue (listener); | |||||
| listeners.remove (listener); | |||||
| if (listeners.size() == 0 && object != 0) | if (listeners.size() == 0 && object != 0) | ||||
| object->valueTreesWithListeners.removeValue (this); | object->valueTreesWithListeners.removeValue (this); | ||||
| @@ -30,6 +30,7 @@ | |||||
| #include "juce_Value.h" | #include "juce_Value.h" | ||||
| #include "../utilities/juce_UndoManager.h" | #include "../utilities/juce_UndoManager.h" | ||||
| #include "../text/juce_XmlElement.h" | #include "../text/juce_XmlElement.h" | ||||
| #include "../events/juce_ListenerList.h" | |||||
| #include "juce_ReferenceCountedArray.h" | #include "juce_ReferenceCountedArray.h" | ||||
| @@ -440,11 +441,7 @@ private: | |||||
| typedef ReferenceCountedObjectPtr <SharedObject> SharedObjectPtr; | typedef ReferenceCountedObjectPtr <SharedObject> SharedObjectPtr; | ||||
| ReferenceCountedObjectPtr <SharedObject> object; | ReferenceCountedObjectPtr <SharedObject> object; | ||||
| SortedSet <Listener*> listeners; | |||||
| void deliverPropertyChangeMessage (ValueTree& tree, const var::identifier& property); | |||||
| void deliverChildChangeMessage (ValueTree& tree); | |||||
| void deliverParentChangeMessage (ValueTree& tree); | |||||
| ListenerList <Listener> listeners; | |||||
| ValueTree (SharedObject* const object_); | ValueTree (SharedObject* const object_); | ||||
| }; | }; | ||||
| @@ -1,156 +1,156 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||||
| Copyright 2004-9 by Raw Material Software Ltd. | |||||
| ------------------------------------------------------------------------------ | |||||
| JUCE can be redistributed and/or modified under the terms of the GNU General | |||||
| Public License (Version 2), as published by the Free Software Foundation. | |||||
| A copy of the license is included in the JUCE distribution, or can be found | |||||
| online at www.gnu.org/licenses. | |||||
| JUCE is distributed in the hope that it will be useful, but WITHOUT ANY | |||||
| WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||||
| A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||||
| ------------------------------------------------------------------------------ | |||||
| To release a closed-source product which uses JUCE, commercial licenses are | |||||
| available: visit www.rawmaterialsoftware.com/juce for more information. | |||||
| ============================================================================== | |||||
| */ | |||||
| #ifndef __JUCE_STANDARDHEADER_JUCEHEADER__ | |||||
| #define __JUCE_STANDARDHEADER_JUCEHEADER__ | |||||
| //============================================================================== | |||||
| /** Current Juce version number. | |||||
| See also SystemStats::getJUCEVersion() for a string version. | |||||
| */ | |||||
| #define JUCE_MAJOR_VERSION 1 | |||||
| #define JUCE_MINOR_VERSION 51 | |||||
| #define JUCE_BUILDNUMBER 7 | |||||
| /** Current Juce version number. | |||||
| Bits 16 to 32 = major version. | |||||
| Bits 8 to 16 = minor version. | |||||
| Bits 0 to 8 = point release (not currently used). | |||||
| See also SystemStats::getJUCEVersion() for a string version. | |||||
| */ | |||||
| #define JUCE_VERSION ((JUCE_MAJOR_VERSION << 16) + (JUCE_MINOR_VERSION << 8) + JUCE_BUILDNUMBER) | |||||
| //============================================================================== | |||||
| #include "juce_TargetPlatform.h" // (sets up the various JUCE_WINDOWS, JUCE_MAC, etc flags) | |||||
| #include "../../juce_Config.h" | |||||
| //============================================================================== | |||||
| #ifdef JUCE_NAMESPACE | |||||
| #define BEGIN_JUCE_NAMESPACE namespace JUCE_NAMESPACE { | |||||
| #define END_JUCE_NAMESPACE } | |||||
| #else | |||||
| #define BEGIN_JUCE_NAMESPACE | |||||
| #define END_JUCE_NAMESPACE | |||||
| #endif | |||||
| //============================================================================== | |||||
| #include "juce_PlatformDefs.h" | |||||
| // Now we'll include any OS headers we need.. (at this point we are outside the Juce namespace). | |||||
| #if JUCE_MSVC | |||||
| #if (defined(_MSC_VER) && (_MSC_VER <= 1200)) | |||||
| #pragma warning (disable: 4284) // (spurious VC6 warning) | |||||
| #endif | |||||
| #pragma warning (push) | |||||
| #pragma warning (disable: 4514 4245 4100) | |||||
| #endif | |||||
| #include <cstdlib> | |||||
| #include <cstdarg> | |||||
| #include <climits> | |||||
| #include <limits> | |||||
| #include <cmath> | |||||
| #include <cwchar> | |||||
| #include <stdexcept> | |||||
| #include <typeinfo> | |||||
| #include <cstring> | |||||
| #include <cstdio> | |||||
| #include <iostream> | |||||
| #if JUCE_USE_INTRINSICS | |||||
| #include <intrin.h> | |||||
| #endif | |||||
| #if JUCE_MAC || JUCE_IPHONE | |||||
| #include <libkern/OSAtomic.h> | |||||
| #endif | |||||
| #if JUCE_LINUX | |||||
| #include <signal.h> | |||||
| #endif | |||||
| #if JUCE_MSVC && JUCE_DEBUG | |||||
| #include <crtdbg.h> | |||||
| #endif | |||||
| #if JUCE_MSVC | |||||
| #include <malloc.h> | |||||
| #pragma warning (pop) | |||||
| #if ! JUCE_PUBLIC_INCLUDES | |||||
| #pragma warning (4: 4511 4512 4100) // (enable some warnings that are turned off in VC8) | |||||
| #endif | |||||
| #endif | |||||
| //============================================================================== | |||||
| // DLL building settings on Win32 | |||||
| #if JUCE_MSVC | |||||
| #ifdef JUCE_DLL_BUILD | |||||
| #define JUCE_API __declspec (dllexport) | |||||
| #pragma warning (disable: 4251) | |||||
| #elif defined (JUCE_DLL) | |||||
| #define JUCE_API __declspec (dllimport) | |||||
| #pragma warning (disable: 4251) | |||||
| #endif | |||||
| #elif defined (__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) | |||||
| #ifdef JUCE_DLL_BUILD | |||||
| #define JUCE_API __attribute__ ((visibility("default"))) | |||||
| #endif | |||||
| #endif | |||||
| #ifndef JUCE_API | |||||
| /** This macro is added to all juce public class declarations. */ | |||||
| #define JUCE_API | |||||
| #endif | |||||
| /** This macro is added to all juce public function declarations. */ | |||||
| #define JUCE_PUBLIC_FUNCTION JUCE_API JUCE_CALLTYPE | |||||
| //============================================================================== | |||||
| // Now include some basics that are needed by most of the Juce classes... | |||||
| BEGIN_JUCE_NAMESPACE | |||||
| extern bool JUCE_PUBLIC_FUNCTION juce_isRunningUnderDebugger(); | |||||
| #if JUCE_LOG_ASSERTIONS | |||||
| extern void JUCE_API juce_LogAssertion (const char* filename, const int lineNum) throw(); | |||||
| #endif | |||||
| #include "juce_Memory.h" | |||||
| #include "juce_MathsFunctions.h" | |||||
| #include "juce_ByteOrder.h" | |||||
| #include "juce_Logger.h" | |||||
| END_JUCE_NAMESPACE | |||||
| #endif // __JUCE_STANDARDHEADER_JUCEHEADER__ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||||
| Copyright 2004-9 by Raw Material Software Ltd. | |||||
| ------------------------------------------------------------------------------ | |||||
| JUCE can be redistributed and/or modified under the terms of the GNU General | |||||
| Public License (Version 2), as published by the Free Software Foundation. | |||||
| A copy of the license is included in the JUCE distribution, or can be found | |||||
| online at www.gnu.org/licenses. | |||||
| JUCE is distributed in the hope that it will be useful, but WITHOUT ANY | |||||
| WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||||
| A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||||
| ------------------------------------------------------------------------------ | |||||
| To release a closed-source product which uses JUCE, commercial licenses are | |||||
| available: visit www.rawmaterialsoftware.com/juce for more information. | |||||
| ============================================================================== | |||||
| */ | |||||
| #ifndef __JUCE_STANDARDHEADER_JUCEHEADER__ | |||||
| #define __JUCE_STANDARDHEADER_JUCEHEADER__ | |||||
| //============================================================================== | |||||
| /** Current Juce version number. | |||||
| See also SystemStats::getJUCEVersion() for a string version. | |||||
| */ | |||||
| #define JUCE_MAJOR_VERSION 1 | |||||
| #define JUCE_MINOR_VERSION 51 | |||||
| #define JUCE_BUILDNUMBER 7 | |||||
| /** Current Juce version number. | |||||
| Bits 16 to 32 = major version. | |||||
| Bits 8 to 16 = minor version. | |||||
| Bits 0 to 8 = point release (not currently used). | |||||
| See also SystemStats::getJUCEVersion() for a string version. | |||||
| */ | |||||
| #define JUCE_VERSION ((JUCE_MAJOR_VERSION << 16) + (JUCE_MINOR_VERSION << 8) + JUCE_BUILDNUMBER) | |||||
| //============================================================================== | |||||
| #include "juce_TargetPlatform.h" // (sets up the various JUCE_WINDOWS, JUCE_MAC, etc flags) | |||||
| #include "../../juce_Config.h" | |||||
| //============================================================================== | |||||
| #ifdef JUCE_NAMESPACE | |||||
| #define BEGIN_JUCE_NAMESPACE namespace JUCE_NAMESPACE { | |||||
| #define END_JUCE_NAMESPACE } | |||||
| #else | |||||
| #define BEGIN_JUCE_NAMESPACE | |||||
| #define END_JUCE_NAMESPACE | |||||
| #endif | |||||
| //============================================================================== | |||||
| #include "juce_PlatformDefs.h" | |||||
| // Now we'll include any OS headers we need.. (at this point we are outside the Juce namespace). | |||||
| #if JUCE_MSVC | |||||
| #if (defined(_MSC_VER) && (_MSC_VER <= 1200)) | |||||
| #pragma warning (disable: 4284) // (spurious VC6 warning) | |||||
| #endif | |||||
| #pragma warning (push) | |||||
| #pragma warning (disable: 4514 4245 4100) | |||||
| #endif | |||||
| #include <cstdlib> | |||||
| #include <cstdarg> | |||||
| #include <climits> | |||||
| #include <limits> | |||||
| #include <cmath> | |||||
| #include <cwchar> | |||||
| #include <stdexcept> | |||||
| #include <typeinfo> | |||||
| #include <cstring> | |||||
| #include <cstdio> | |||||
| #include <iostream> | |||||
| #if JUCE_USE_INTRINSICS | |||||
| #include <intrin.h> | |||||
| #endif | |||||
| #if JUCE_MAC || JUCE_IPHONE | |||||
| #include <libkern/OSAtomic.h> | |||||
| #endif | |||||
| #if JUCE_LINUX | |||||
| #include <signal.h> | |||||
| #endif | |||||
| #if JUCE_MSVC && JUCE_DEBUG | |||||
| #include <crtdbg.h> | |||||
| #endif | |||||
| #if JUCE_MSVC | |||||
| #include <malloc.h> | |||||
| #pragma warning (pop) | |||||
| #if ! JUCE_PUBLIC_INCLUDES | |||||
| #pragma warning (4: 4511 4512 4100) // (enable some warnings that are turned off in VC8) | |||||
| #endif | |||||
| #endif | |||||
| //============================================================================== | |||||
| // DLL building settings on Win32 | |||||
| #if JUCE_MSVC | |||||
| #ifdef JUCE_DLL_BUILD | |||||
| #define JUCE_API __declspec (dllexport) | |||||
| #pragma warning (disable: 4251) | |||||
| #elif defined (JUCE_DLL) | |||||
| #define JUCE_API __declspec (dllimport) | |||||
| #pragma warning (disable: 4251) | |||||
| #endif | |||||
| #elif defined (__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) | |||||
| #ifdef JUCE_DLL_BUILD | |||||
| #define JUCE_API __attribute__ ((visibility("default"))) | |||||
| #endif | |||||
| #endif | |||||
| #ifndef JUCE_API | |||||
| /** This macro is added to all juce public class declarations. */ | |||||
| #define JUCE_API | |||||
| #endif | |||||
| /** This macro is added to all juce public function declarations. */ | |||||
| #define JUCE_PUBLIC_FUNCTION JUCE_API JUCE_CALLTYPE | |||||
| //============================================================================== | |||||
| // Now include some basics that are needed by most of the Juce classes... | |||||
| BEGIN_JUCE_NAMESPACE | |||||
| extern bool JUCE_PUBLIC_FUNCTION juce_isRunningUnderDebugger(); | |||||
| #if JUCE_LOG_ASSERTIONS | |||||
| extern void JUCE_API juce_LogAssertion (const char* filename, const int lineNum) throw(); | |||||
| #endif | |||||
| #include "juce_Memory.h" | |||||
| #include "juce_MathsFunctions.h" | |||||
| #include "juce_ByteOrder.h" | |||||
| #include "juce_Logger.h" | |||||
| END_JUCE_NAMESPACE | |||||
| #endif // __JUCE_STANDARDHEADER_JUCEHEADER__ | |||||
| @@ -0,0 +1,315 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||||
| Copyright 2004-9 by Raw Material Software Ltd. | |||||
| ------------------------------------------------------------------------------ | |||||
| JUCE can be redistributed and/or modified under the terms of the GNU General | |||||
| Public License (Version 2), as published by the Free Software Foundation. | |||||
| A copy of the license is included in the JUCE distribution, or can be found | |||||
| online at www.gnu.org/licenses. | |||||
| JUCE is distributed in the hope that it will be useful, but WITHOUT ANY | |||||
| WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||||
| A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||||
| ------------------------------------------------------------------------------ | |||||
| To release a closed-source product which uses JUCE, commercial licenses are | |||||
| available: visit www.rawmaterialsoftware.com/juce for more information. | |||||
| ============================================================================== | |||||
| */ | |||||
| #ifndef __JUCE_LISTENERLIST_JUCEHEADER__ | |||||
| #define __JUCE_LISTENERLIST_JUCEHEADER__ | |||||
| #include "../containers/juce_Array.h" | |||||
| //============================================================================== | |||||
| /** | |||||
| Holds a set of objects and can invoke a member function callback on each object | |||||
| in the set with a single call. | |||||
| Use a ListenerList to manage a set of objects which need a callback, and you | |||||
| can invoke a member function by simply calling call() or callChecked(). | |||||
| E.g. | |||||
| @code | |||||
| class MyListenerType | |||||
| { | |||||
| public: | |||||
| void myCallbackMethod (int foo, bool bar); | |||||
| }; | |||||
| ListenerList <MyListenerType> listeners; | |||||
| listeners.add (someCallbackObjects...); | |||||
| // This will invoke myCallbackMethod (1234, true) on each of the objects | |||||
| // in the list... | |||||
| listeners.call (&MyListenerType::myCallbackMethod, 1234, true); | |||||
| @endcode | |||||
| If you add or remove listeners from the list during one of the callbacks - i.e. while | |||||
| it's in the middle of iterating the listeners, then it's guaranteed that no listeners | |||||
| will be mistakenly called after they've been removed, but it may mean that some of the | |||||
| listeners could be called more than once, or not at all, depending on the list's order. | |||||
| Sometimes, there's a chance that invoking one of the callbacks might result in the | |||||
| list itself being deleted while it's still iterating - to survive this situation, you can | |||||
| use callChecked() instead of call(), passing it a local object to act as a "BailOutChecker". | |||||
| The BailOutChecker must implement a method of the form "bool shouldBailOut()", and | |||||
| the list will check this after each callback to determine whether it should abort the | |||||
| operation. For an example of a bail-out checker, see the Component::BailOutChecker class, | |||||
| which can be used to check when a Component has been deleted. See also | |||||
| ListenerList::DummyBailOutChecker, which is a dummy checker that always returns false. | |||||
| */ | |||||
| template <class ListenerClass, | |||||
| class ArrayType = Array <ListenerClass*> > | |||||
| class ListenerList | |||||
| { | |||||
| public: | |||||
| //============================================================================== | |||||
| /** Creates an empty list. */ | |||||
| ListenerList() | |||||
| { | |||||
| } | |||||
| /** Destructor. */ | |||||
| ~ListenerList() | |||||
| { | |||||
| } | |||||
| //============================================================================== | |||||
| /** Adds a listener to the list. | |||||
| A listener can only be added once, so if the listener is already in the list, | |||||
| this method has no effect. | |||||
| @see remove | |||||
| */ | |||||
| void add (ListenerClass* const listenerToAdd) | |||||
| { | |||||
| // Listeners can't be null pointers! | |||||
| jassert (listenerToAdd != 0); | |||||
| if (listenerToAdd != 0) | |||||
| listeners.add (listenerToAdd); | |||||
| } | |||||
| /** Removes a listener from the list. | |||||
| If the listener wasn't in the list, this has no effect. | |||||
| */ | |||||
| void remove (ListenerClass* const listenerToRemove) | |||||
| { | |||||
| // Listeners can't be null pointers! | |||||
| jassert (listenerToRemove != 0); | |||||
| listeners.removeValue (listenerToRemove); | |||||
| } | |||||
| /** Returns the number of registered listeners. */ | |||||
| int size() const throw() | |||||
| { | |||||
| return listeners.size(); | |||||
| } | |||||
| /** Returns true if any listeners are registered. */ | |||||
| bool isEmpty() const throw() | |||||
| { | |||||
| return listeners.size() == 0; | |||||
| } | |||||
| /** Returns true if the specified listener has been added to the list. */ | |||||
| bool contains (ListenerClass* const listener) const throw() | |||||
| { | |||||
| return listeners.contains (listener); | |||||
| } | |||||
| //============================================================================== | |||||
| /** Calls a member function on each listener in the list, with no parameters. */ | |||||
| void call (void (ListenerClass::*callbackFunction) ()) | |||||
| { | |||||
| callChecked (DummyBailOutChecker(), callbackFunction); | |||||
| } | |||||
| /** Calls a member function on each listener in the list, with no parameters and a bail-out-checker. | |||||
| See the class description for info about writing a bail-out checker. */ | |||||
| template <class BailOutCheckerType> | |||||
| void callChecked (const BailOutCheckerType& bailOutChecker, | |||||
| void (ListenerClass::*callbackFunction) ()) | |||||
| { | |||||
| for (Iterator<BailOutCheckerType> iter (*this, bailOutChecker); iter.next();) | |||||
| (iter.getListener()->*callbackFunction) (); | |||||
| } | |||||
| //============================================================================== | |||||
| /** Calls a member function on each listener in the list, with 1 parameter. */ | |||||
| template <typename P1, typename P2> | |||||
| void call (void (ListenerClass::*callbackFunction) (P1), | |||||
| P2& param1) | |||||
| { | |||||
| for (Iterator<DummyBailOutChecker> iter (*this, DummyBailOutChecker()); iter.next();) | |||||
| (iter.getListener()->*callbackFunction) (param1); | |||||
| } | |||||
| /** Calls a member function on each listener in the list, with one parameter and a bail-out-checker. | |||||
| See the class description for info about writing a bail-out checker. */ | |||||
| template <class BailOutCheckerType, typename P1, typename P2> | |||||
| void callChecked (const BailOutCheckerType& bailOutChecker, | |||||
| void (ListenerClass::*callbackFunction) (P1), | |||||
| P2& param1) | |||||
| { | |||||
| for (Iterator<BailOutCheckerType> iter (*this, bailOutChecker); iter.next();) | |||||
| (iter.getListener()->*callbackFunction) (param1); | |||||
| } | |||||
| //============================================================================== | |||||
| /** Calls a member function on each listener in the list, with 2 parameters. */ | |||||
| template <typename P1, typename P2, typename P3, typename P4> | |||||
| void call (void (ListenerClass::*callbackFunction) (P1, P2), | |||||
| P3& param1, P4& param2) | |||||
| { | |||||
| for (Iterator<DummyBailOutChecker> iter (*this, DummyBailOutChecker()); iter.next();) | |||||
| (iter.getListener()->*callbackFunction) (param1, param2); | |||||
| } | |||||
| /** Calls a member function on each listener in the list, with 2 parameters and a bail-out-checker. | |||||
| See the class description for info about writing a bail-out checker. */ | |||||
| template <class BailOutCheckerType, typename P1, typename P2, typename P3, typename P4> | |||||
| void callChecked (const BailOutCheckerType& bailOutChecker, | |||||
| void (ListenerClass::*callbackFunction) (P1, P2), | |||||
| P3& param1, P4& param2) | |||||
| { | |||||
| for (Iterator<BailOutCheckerType> iter (*this, bailOutChecker); iter.next();) | |||||
| (iter.getListener()->*callbackFunction) (param1, param2); | |||||
| } | |||||
| //============================================================================== | |||||
| /** Calls a member function on each listener in the list, with 3 parameters. */ | |||||
| template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6> | |||||
| void call (void (ListenerClass::*callbackFunction) (P1, P2, P3), | |||||
| P4& param1, P5& param2, P6& param3) | |||||
| { | |||||
| for (Iterator<DummyBailOutChecker> iter (*this, DummyBailOutChecker()); iter.next();) | |||||
| (iter.getListener()->*callbackFunction) (param1, param2, param3); | |||||
| } | |||||
| /** Calls a member function on each listener in the list, with 3 parameters and a bail-out-checker. | |||||
| See the class description for info about writing a bail-out checker. */ | |||||
| template <class BailOutCheckerType, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6> | |||||
| void callChecked (const BailOutCheckerType& bailOutChecker, | |||||
| void (ListenerClass::*callbackFunction) (P1, P2, P3), | |||||
| P4& param1, P5& param2, P6& param3) | |||||
| { | |||||
| for (Iterator<BailOutCheckerType> iter (*this, bailOutChecker); iter.next();) | |||||
| (iter.getListener()->*callbackFunction) (param1, param2, param3); | |||||
| } | |||||
| //============================================================================== | |||||
| /** Calls a member function on each listener in the list, with 4 parameters. */ | |||||
| template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8> | |||||
| void call (void (ListenerClass::*callbackFunction) (P1, P2, P3, P4), | |||||
| P5& param1, P6& param2, P7& param3, P8& param4) | |||||
| { | |||||
| for (Iterator<DummyBailOutChecker> iter (*this, DummyBailOutChecker()); iter.next();) | |||||
| (iter.getListener()->*callbackFunction) (param1, param2, param3, param4); | |||||
| } | |||||
| /** Calls a member function on each listener in the list, with 4 parameters and a bail-out-checker. | |||||
| See the class description for info about writing a bail-out checker. */ | |||||
| template <class BailOutCheckerType, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8> | |||||
| void callChecked (const BailOutCheckerType& bailOutChecker, | |||||
| void (ListenerClass::*callbackFunction) (P1, P2, P3, P4), | |||||
| P5& param1, P6& param2, P7& param3, P8& param4) | |||||
| { | |||||
| for (Iterator<BailOutCheckerType> iter (*this, bailOutChecker); iter.next();) | |||||
| (iter.getListener()->*callbackFunction) (param1, param2, param3, param4); | |||||
| } | |||||
| //============================================================================== | |||||
| /** Calls a member function on each listener in the list, with 5 parameters. */ | |||||
| template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10> | |||||
| void call (void (ListenerClass::*callbackFunction) (P1, P2, P3, P4, P5), | |||||
| P6& param1, P7& param2, P8& param3, P9& param4, P10& param5) | |||||
| { | |||||
| for (Iterator<DummyBailOutChecker> iter (*this, DummyBailOutChecker()); iter.next();) | |||||
| (iter.getListener()->*callbackFunction) (param1, param2, param3, param4, param5); | |||||
| } | |||||
| /** Calls a member function on each listener in the list, with 5 parameters and a bail-out-checker. | |||||
| See the class description for info about writing a bail-out checker. */ | |||||
| template <class BailOutCheckerType, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10> | |||||
| void callChecked (const BailOutCheckerType& bailOutChecker, | |||||
| void (ListenerClass::*callbackFunction) (P1, P2, P3, P4, P5), | |||||
| P6& param1, P7& param2, P8& param3, P9& param4, P10& param5) | |||||
| { | |||||
| for (Iterator<BailOutCheckerType> iter (*this, bailOutChecker); iter.next();) | |||||
| (iter.getListener()->*callbackFunction) (param1, param2, param3, param4, param5); | |||||
| } | |||||
| //============================================================================== | |||||
| /** A dummy bail-out checker that always returns false. | |||||
| See the ListenerList notes for more info about bail-out checkers. | |||||
| */ | |||||
| class DummyBailOutChecker | |||||
| { | |||||
| public: | |||||
| inline bool shouldBailOut() const throw() { return false; } | |||||
| }; | |||||
| //============================================================================== | |||||
| /** Iterates the listeners in a ListenerList. */ | |||||
| template <class BailOutCheckerType> | |||||
| class Iterator | |||||
| { | |||||
| public: | |||||
| //============================================================================== | |||||
| Iterator (const ListenerList& list_, const BailOutCheckerType& bailOutChecker_) | |||||
| : list (list_), bailOutChecker (bailOutChecker_), index (list_.size()) | |||||
| {} | |||||
| ~Iterator() {} | |||||
| //============================================================================== | |||||
| bool next() | |||||
| { | |||||
| if (index <= 0 || bailOutChecker.shouldBailOut()) | |||||
| return false; | |||||
| const int listSize = list.size(); | |||||
| if (--index < listSize) | |||||
| return true; | |||||
| index = listSize - 1; | |||||
| return index >= 0; | |||||
| } | |||||
| ListenerClass* getListener() const throw() | |||||
| { | |||||
| return list.listeners.getUnchecked (index); | |||||
| } | |||||
| //============================================================================== | |||||
| private: | |||||
| const ListenerList& list; | |||||
| const BailOutCheckerType& bailOutChecker; | |||||
| int index; | |||||
| Iterator (const Iterator&); | |||||
| Iterator& operator= (const Iterator&); | |||||
| }; | |||||
| private: | |||||
| //============================================================================== | |||||
| ArrayType listeners; | |||||
| ListenerList (const ListenerList&); | |||||
| ListenerList& operator= (const ListenerList&); | |||||
| }; | |||||
| #endif // __JUCE_LISTENERLIST_JUCEHEADER__ | |||||
| @@ -52,7 +52,6 @@ private: | |||||
| //============================================================================== | //============================================================================== | ||||
| Button::Button (const String& name) | Button::Button (const String& name) | ||||
| : Component (name), | : Component (name), | ||||
| keySource (0), | |||||
| text (name), | text (name), | ||||
| buttonPressTime (0), | buttonPressTime (0), | ||||
| lastTimeCallbackTime (0), | lastTimeCallbackTime (0), | ||||
| @@ -352,23 +351,17 @@ void Button::handleCommandMessage (int commandId) | |||||
| //============================================================================== | //============================================================================== | ||||
| void Button::addButtonListener (ButtonListener* const newListener) | void Button::addButtonListener (ButtonListener* const newListener) | ||||
| { | { | ||||
| jassert (newListener != 0); | |||||
| jassert (! buttonListeners.contains (newListener)); // trying to add a listener to the list twice! | |||||
| if (newListener != 0) | |||||
| buttonListeners.add (newListener); | |||||
| buttonListeners.add (newListener); | |||||
| } | } | ||||
| void Button::removeButtonListener (ButtonListener* const listener) | void Button::removeButtonListener (ButtonListener* const listener) | ||||
| { | { | ||||
| jassert (buttonListeners.contains (listener)); // trying to remove a listener that isn't on the list! | |||||
| buttonListeners.removeValue (listener); | |||||
| buttonListeners.remove (listener); | |||||
| } | } | ||||
| void Button::sendClickMessage (const ModifierKeys& modifiers) | void Button::sendClickMessage (const ModifierKeys& modifiers) | ||||
| { | { | ||||
| Component::SafePointer<Component> deletionWatcher (this); | |||||
| Component::BailOutChecker checker (this); | |||||
| if (commandManagerToUse != 0 && commandID != 0) | if (commandManagerToUse != 0 && commandID != 0) | ||||
| { | { | ||||
| @@ -381,44 +374,18 @@ void Button::sendClickMessage (const ModifierKeys& modifiers) | |||||
| clicked (modifiers); | clicked (modifiers); | ||||
| if (deletionWatcher != 0) | |||||
| { | |||||
| for (int i = buttonListeners.size(); --i >= 0;) | |||||
| { | |||||
| ButtonListener* const bl = (ButtonListener*) buttonListeners[i]; | |||||
| if (bl != 0) | |||||
| { | |||||
| bl->buttonClicked (this); | |||||
| if (deletionWatcher == 0) | |||||
| return; | |||||
| } | |||||
| } | |||||
| } | |||||
| if (! checker.shouldBailOut()) | |||||
| buttonListeners.callChecked (checker, &ButtonListener::buttonClicked, this); | |||||
| } | } | ||||
| void Button::sendStateMessage() | void Button::sendStateMessage() | ||||
| { | { | ||||
| Component::SafePointer<Component> deletionWatcher (this); | |||||
| Component::BailOutChecker checker (this); | |||||
| buttonStateChanged(); | buttonStateChanged(); | ||||
| if (deletionWatcher == 0) | |||||
| return; | |||||
| for (int i = buttonListeners.size(); --i >= 0;) | |||||
| { | |||||
| ButtonListener* const bl = (ButtonListener*) buttonListeners[i]; | |||||
| if (bl != 0) | |||||
| { | |||||
| bl->buttonStateChanged (this); | |||||
| if (deletionWatcher == 0) | |||||
| return; | |||||
| } | |||||
| } | |||||
| if (! checker.shouldBailOut()) | |||||
| buttonListeners.callChecked (checker, &ButtonListener::buttonStateChanged, this); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -512,12 +479,12 @@ void Button::parentHierarchyChanged() | |||||
| if (newKeySource != keySource) | if (newKeySource != keySource) | ||||
| { | { | ||||
| if (keySource->isValidComponent()) | |||||
| if (keySource != 0) | |||||
| keySource->removeKeyListener (this); | keySource->removeKeyListener (this); | ||||
| keySource = newKeySource; | keySource = newKeySource; | ||||
| if (keySource->isValidComponent()) | |||||
| if (keySource != 0) | |||||
| keySource->addKeyListener (this); | keySource->addKeyListener (this); | ||||
| } | } | ||||
| } | } | ||||
| @@ -469,9 +469,9 @@ protected: | |||||
| private: | private: | ||||
| //============================================================================== | //============================================================================== | ||||
| Array <KeyPress> shortcuts; | Array <KeyPress> shortcuts; | ||||
| Component* keySource; | |||||
| Component::SafePointer<Component> keySource; | |||||
| String text; | String text; | ||||
| SortedSet <void*> buttonListeners; | |||||
| ListenerList <ButtonListener> buttonListeners; | |||||
| class RepeatTimer; | class RepeatTimer; | ||||
| friend class RepeatTimer; | friend class RepeatTimer; | ||||
| @@ -605,23 +605,18 @@ void ComboBox::mouseUp (const MouseEvent& e2) | |||||
| //============================================================================== | //============================================================================== | ||||
| void ComboBox::addListener (ComboBoxListener* const listener) throw() | void ComboBox::addListener (ComboBoxListener* const listener) throw() | ||||
| { | { | ||||
| jassert (listener != 0); | |||||
| if (listener != 0) | |||||
| listeners.add (listener); | |||||
| listeners.add (listener); | |||||
| } | } | ||||
| void ComboBox::removeListener (ComboBoxListener* const listener) throw() | void ComboBox::removeListener (ComboBoxListener* const listener) throw() | ||||
| { | { | ||||
| listeners.removeValue (listener); | |||||
| listeners.remove (listener); | |||||
| } | } | ||||
| void ComboBox::handleAsyncUpdate() | void ComboBox::handleAsyncUpdate() | ||||
| { | { | ||||
| for (int i = listeners.size(); --i >= 0;) | |||||
| { | |||||
| ((ComboBoxListener*) listeners.getUnchecked (i))->comboBoxChanged (this); | |||||
| i = jmin (i, listeners.size()); | |||||
| } | |||||
| Component::BailOutChecker checker (this); | |||||
| listeners.callChecked (checker, &ComboBoxListener::comboBoxChanged, this); | |||||
| } | } | ||||
| @@ -392,7 +392,7 @@ private: | |||||
| Value currentId; | Value currentId; | ||||
| int lastCurrentId; | int lastCurrentId; | ||||
| bool isButtonDown, separatorPending, menuActive, textIsCustom; | bool isButtonDown, separatorPending, menuActive, textIsCustom; | ||||
| SortedSet <void*> listeners; | |||||
| ListenerList <ComboBoxListener> listeners; | |||||
| ScopedPointer<Label> label; | ScopedPointer<Label> label; | ||||
| String textWhenNothingSelected, noChoicesMessage; | String textWhenNothingSelected, noChoicesMessage; | ||||
| @@ -140,7 +140,7 @@ void Label::setBorderSize (int h, int v) | |||||
| //============================================================================== | //============================================================================== | ||||
| Component* Label::getAttachedComponent() const | Component* Label::getAttachedComponent() const | ||||
| { | { | ||||
| return const_cast <Component*> (static_cast <const Component*> (ownerComponent)); | |||||
| return static_cast<Component*> (ownerComponent); | |||||
| } | } | ||||
| void Label::attachToComponent (Component* owner, | void Label::attachToComponent (Component* owner, | ||||
| @@ -257,6 +257,8 @@ void Label::hideEditor (const bool discardCurrentEditorContents) | |||||
| { | { | ||||
| if (editor != 0) | if (editor != 0) | ||||
| { | { | ||||
| Component::SafePointer<Component> deletionChecker (this); | |||||
| editorAboutToBeHidden (editor); | editorAboutToBeHidden (editor); | ||||
| const bool changed = (! discardCurrentEditorContents) | const bool changed = (! discardCurrentEditorContents) | ||||
| @@ -268,9 +270,10 @@ void Label::hideEditor (const bool discardCurrentEditorContents) | |||||
| if (changed) | if (changed) | ||||
| textWasEdited(); | textWasEdited(); | ||||
| exitModalState (0); | |||||
| if (deletionChecker != 0) | |||||
| exitModalState (0); | |||||
| if (changed && isValidComponent()) | |||||
| if (changed && deletionChecker != 0) | |||||
| callChangeListeners(); | callChangeListeners(); | ||||
| } | } | ||||
| } | } | ||||
| @@ -395,23 +398,18 @@ KeyboardFocusTraverser* Label::createFocusTraverser() | |||||
| //============================================================================== | //============================================================================== | ||||
| void Label::addListener (LabelListener* const listener) throw() | void Label::addListener (LabelListener* const listener) throw() | ||||
| { | { | ||||
| jassert (listener != 0); | |||||
| if (listener != 0) | |||||
| listeners.add (listener); | |||||
| listeners.add (listener); | |||||
| } | } | ||||
| void Label::removeListener (LabelListener* const listener) throw() | void Label::removeListener (LabelListener* const listener) throw() | ||||
| { | { | ||||
| listeners.removeValue (listener); | |||||
| listeners.remove (listener); | |||||
| } | } | ||||
| void Label::callChangeListeners() | void Label::callChangeListeners() | ||||
| { | { | ||||
| for (int i = listeners.size(); --i >= 0;) | |||||
| { | |||||
| ((LabelListener*) listeners.getUnchecked (i))->labelTextChanged (this); | |||||
| i = jmin (i, listeners.size()); | |||||
| } | |||||
| Component::BailOutChecker checker (this); | |||||
| listeners.callChecked (checker, &LabelListener::labelTextChanged, this); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -443,9 +441,10 @@ void Label::textEditorReturnKeyPressed (TextEditor& ed) | |||||
| if (changed) | if (changed) | ||||
| { | { | ||||
| Component::SafePointer<Component> deletionChecker (this); | |||||
| textWasEdited(); | textWasEdited(); | ||||
| if (isValidComponent()) | |||||
| if (deletionChecker != 0) | |||||
| callChangeListeners(); | callChangeListeners(); | ||||
| } | } | ||||
| } | } | ||||
| @@ -327,7 +327,7 @@ private: | |||||
| Font font; | Font font; | ||||
| Justification justification; | Justification justification; | ||||
| ScopedPointer <TextEditor> editor; | ScopedPointer <TextEditor> editor; | ||||
| SortedSet <void*> listeners; | |||||
| ListenerList <LabelListener> listeners; | |||||
| Component::SafePointer<Component> ownerComponent; | Component::SafePointer<Component> ownerComponent; | ||||
| int horizontalBorderSize, verticalBorderSize; | int horizontalBorderSize, verticalBorderSize; | ||||
| float minimumHorizontalScale; | float minimumHorizontalScale; | ||||
| @@ -158,22 +158,16 @@ void Slider::handleAsyncUpdate() | |||||
| { | { | ||||
| cancelPendingUpdate(); | cancelPendingUpdate(); | ||||
| for (int i = listeners.size(); --i >= 0;) | |||||
| { | |||||
| ((SliderListener*) listeners.getUnchecked (i))->sliderValueChanged (this); | |||||
| i = jmin (i, listeners.size()); | |||||
| } | |||||
| Component::BailOutChecker checker (this); | |||||
| listeners.callChecked (checker, &SliderListener::sliderValueChanged, this); | |||||
| } | } | ||||
| void Slider::sendDragStart() | void Slider::sendDragStart() | ||||
| { | { | ||||
| startedDragging(); | startedDragging(); | ||||
| for (int i = listeners.size(); --i >= 0;) | |||||
| { | |||||
| ((SliderListener*) listeners.getUnchecked (i))->sliderDragStarted (this); | |||||
| i = jmin (i, listeners.size()); | |||||
| } | |||||
| Component::BailOutChecker checker (this); | |||||
| listeners.callChecked (checker, &SliderListener::sliderDragStarted, this); | |||||
| } | } | ||||
| void Slider::sendDragEnd() | void Slider::sendDragEnd() | ||||
| @@ -182,23 +176,18 @@ void Slider::sendDragEnd() | |||||
| sliderBeingDragged = -1; | sliderBeingDragged = -1; | ||||
| for (int i = listeners.size(); --i >= 0;) | |||||
| { | |||||
| ((SliderListener*) listeners.getUnchecked (i))->sliderDragEnded (this); | |||||
| i = jmin (i, listeners.size()); | |||||
| } | |||||
| Component::BailOutChecker checker (this); | |||||
| listeners.callChecked (checker, &SliderListener::sliderDragEnded, this); | |||||
| } | } | ||||
| void Slider::addListener (SliderListener* const listener) | void Slider::addListener (SliderListener* const listener) | ||||
| { | { | ||||
| jassert (listener != 0); | |||||
| if (listener != 0) | |||||
| listeners.add (listener); | |||||
| listeners.add (listener); | |||||
| } | } | ||||
| void Slider::removeListener (SliderListener* const listener) | void Slider::removeListener (SliderListener* const listener) | ||||
| { | { | ||||
| listeners.removeValue (listener); | |||||
| listeners.remove (listener); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -30,7 +30,6 @@ | |||||
| #include "juce_Label.h" | #include "juce_Label.h" | ||||
| #include "../buttons/juce_Button.h" | #include "../buttons/juce_Button.h" | ||||
| #include "../../../events/juce_AsyncUpdater.h" | #include "../../../events/juce_AsyncUpdater.h" | ||||
| #include "../../../containers/juce_SortedSet.h" | |||||
| #include "../../../containers/juce_Value.h" | #include "../../../containers/juce_Value.h" | ||||
| @@ -750,7 +749,7 @@ protected: | |||||
| void valueChanged (Value& value); | void valueChanged (Value& value); | ||||
| private: | private: | ||||
| SortedSet <void*> listeners; | |||||
| ListenerList <SliderListener> listeners; | |||||
| Value currentValue, valueMin, valueMax; | Value currentValue, valueMin, valueMax; | ||||
| double lastCurrentValue, lastValueMin, lastValueMax; | double lastCurrentValue, lastValueMin, lastValueMax; | ||||
| double minimum, maximum, interval, doubleClickReturnValue; | double minimum, maximum, interval, doubleClickReturnValue; | ||||
| @@ -1258,15 +1258,12 @@ void TextEditor::escapePressed() | |||||
| void TextEditor::addListener (TextEditorListener* const newListener) | void TextEditor::addListener (TextEditorListener* const newListener) | ||||
| { | { | ||||
| jassert (newListener != 0) | |||||
| if (newListener != 0) | |||||
| listeners.add (newListener); | |||||
| listeners.add (newListener); | |||||
| } | } | ||||
| void TextEditor::removeListener (TextEditorListener* const listenerToRemove) | void TextEditor::removeListener (TextEditorListener* const listenerToRemove) | ||||
| { | { | ||||
| listeners.removeValue (listenerToRemove); | |||||
| listeners.remove (listenerToRemove); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -2166,47 +2163,36 @@ void TextEditor::resized() | |||||
| void TextEditor::handleCommandMessage (const int commandId) | void TextEditor::handleCommandMessage (const int commandId) | ||||
| { | { | ||||
| Component::SafePointer<Component> deletionChecker (this); | |||||
| Component::BailOutChecker checker (this); | |||||
| for (int i = listeners.size(); --i >= 0;) | |||||
| switch (commandId) | |||||
| { | { | ||||
| TextEditorListener* const tl = (TextEditorListener*) listeners [i]; | |||||
| if (tl != 0) | |||||
| { | |||||
| switch (commandId) | |||||
| { | |||||
| case TextEditorDefs::textChangeMessageId: | |||||
| tl->textEditorTextChanged (*this); | |||||
| break; | |||||
| case TextEditorDefs::returnKeyMessageId: | |||||
| tl->textEditorReturnKeyPressed (*this); | |||||
| break; | |||||
| case TextEditorDefs::textChangeMessageId: | |||||
| listeners.callChecked (checker, &TextEditorListener::textEditorTextChanged, (TextEditor&) *this); | |||||
| break; | |||||
| case TextEditorDefs::escapeKeyMessageId: | |||||
| tl->textEditorEscapeKeyPressed (*this); | |||||
| break; | |||||
| case TextEditorDefs::returnKeyMessageId: | |||||
| listeners.callChecked (checker, &TextEditorListener::textEditorReturnKeyPressed, (TextEditor&) *this); | |||||
| break; | |||||
| case TextEditorDefs::focusLossMessageId: | |||||
| tl->textEditorFocusLost (*this); | |||||
| break; | |||||
| case TextEditorDefs::escapeKeyMessageId: | |||||
| listeners.callChecked (checker, &TextEditorListener::textEditorEscapeKeyPressed, (TextEditor&) *this); | |||||
| break; | |||||
| default: | |||||
| jassertfalse | |||||
| break; | |||||
| } | |||||
| case TextEditorDefs::focusLossMessageId: | |||||
| listeners.callChecked (checker, &TextEditorListener::textEditorFocusLost, (TextEditor&) *this); | |||||
| break; | |||||
| if (deletionChecker == 0) | |||||
| return; | |||||
| } | |||||
| default: | |||||
| jassertfalse | |||||
| break; | |||||
| } | } | ||||
| } | } | ||||
| void TextEditor::enablementChanged() | void TextEditor::enablementChanged() | ||||
| { | { | ||||
| setMouseCursor (MouseCursor (isReadOnly() ? MouseCursor::NormalCursor | |||||
| : MouseCursor::IBeamCursor)); | |||||
| setMouseCursor (isReadOnly() ? MouseCursor::NormalCursor | |||||
| : MouseCursor::IBeamCursor); | |||||
| repaint(); | repaint(); | ||||
| } | } | ||||
| @@ -652,7 +652,7 @@ private: | |||||
| } dragType; | } dragType; | ||||
| String allowedCharacters; | String allowedCharacters; | ||||
| SortedSet <void*> listeners; | |||||
| ListenerList <TextEditorListener> listeners; | |||||
| friend class TextEditorInsertAction; | friend class TextEditorInsertAction; | ||||
| friend class TextEditorRemoveAction; | friend class TextEditorRemoveAction; | ||||
| @@ -47,47 +47,26 @@ FileBrowserListener::~FileBrowserListener() | |||||
| void DirectoryContentsDisplayComponent::addListener (FileBrowserListener* const listener) throw() | void DirectoryContentsDisplayComponent::addListener (FileBrowserListener* const listener) throw() | ||||
| { | { | ||||
| jassert (listener != 0); | |||||
| if (listener != 0) | |||||
| listeners.add (listener); | |||||
| listeners.add (listener); | |||||
| } | } | ||||
| void DirectoryContentsDisplayComponent::removeListener (FileBrowserListener* const listener) throw() | void DirectoryContentsDisplayComponent::removeListener (FileBrowserListener* const listener) throw() | ||||
| { | { | ||||
| listeners.removeValue (listener); | |||||
| listeners.remove (listener); | |||||
| } | } | ||||
| void DirectoryContentsDisplayComponent::sendSelectionChangeMessage() | void DirectoryContentsDisplayComponent::sendSelectionChangeMessage() | ||||
| { | { | ||||
| Component::SafePointer<Component> deletionWatcher (dynamic_cast <Component*> (this)); | |||||
| for (int i = listeners.size(); --i >= 0;) | |||||
| { | |||||
| ((FileBrowserListener*) listeners.getUnchecked (i))->selectionChanged(); | |||||
| if (deletionWatcher == 0) | |||||
| return; | |||||
| i = jmin (i, listeners.size() - 1); | |||||
| } | |||||
| Component::BailOutChecker checker (dynamic_cast <Component*> (this)); | |||||
| listeners.callChecked (checker, &FileBrowserListener::selectionChanged); | |||||
| } | } | ||||
| void DirectoryContentsDisplayComponent::sendMouseClickMessage (const File& file, const MouseEvent& e) | void DirectoryContentsDisplayComponent::sendMouseClickMessage (const File& file, const MouseEvent& e) | ||||
| { | { | ||||
| if (fileList.getDirectory().exists()) | if (fileList.getDirectory().exists()) | ||||
| { | { | ||||
| Component::SafePointer<Component> deletionWatcher (dynamic_cast <Component*> (this)); | |||||
| for (int i = listeners.size(); --i >= 0;) | |||||
| { | |||||
| ((FileBrowserListener*) listeners.getUnchecked (i))->fileClicked (file, e); | |||||
| if (deletionWatcher == 0) | |||||
| return; | |||||
| i = jmin (i, listeners.size() - 1); | |||||
| } | |||||
| Component::BailOutChecker checker (dynamic_cast <Component*> (this)); | |||||
| listeners.callChecked (checker, &FileBrowserListener::fileClicked, file, e); | |||||
| } | } | ||||
| } | } | ||||
| @@ -95,17 +74,8 @@ void DirectoryContentsDisplayComponent::sendDoubleClickMessage (const File& file | |||||
| { | { | ||||
| if (fileList.getDirectory().exists()) | if (fileList.getDirectory().exists()) | ||||
| { | { | ||||
| Component::SafePointer<Component> deletionWatcher (dynamic_cast <Component*> (this)); | |||||
| for (int i = listeners.size(); --i >= 0;) | |||||
| { | |||||
| ((FileBrowserListener*) listeners.getUnchecked (i))->fileDoubleClicked (file); | |||||
| if (deletionWatcher == 0) | |||||
| return; | |||||
| i = jmin (i, listeners.size() - 1); | |||||
| } | |||||
| Component::BailOutChecker checker (dynamic_cast <Component*> (this)); | |||||
| listeners.callChecked (checker, &FileBrowserListener::fileDoubleClicked, file); | |||||
| } | } | ||||
| } | } | ||||
| @@ -104,7 +104,7 @@ public: | |||||
| protected: | protected: | ||||
| DirectoryContentsList& fileList; | DirectoryContentsList& fileList; | ||||
| SortedSet <void*> listeners; | |||||
| ListenerList <FileBrowserListener> listeners; | |||||
| DirectoryContentsDisplayComponent (const DirectoryContentsDisplayComponent&); | DirectoryContentsDisplayComponent (const DirectoryContentsDisplayComponent&); | ||||
| DirectoryContentsDisplayComponent& operator= (const DirectoryContentsDisplayComponent&); | DirectoryContentsDisplayComponent& operator= (const DirectoryContentsDisplayComponent&); | ||||
| @@ -152,15 +152,12 @@ FileBrowserComponent::~FileBrowserComponent() | |||||
| //============================================================================== | //============================================================================== | ||||
| void FileBrowserComponent::addListener (FileBrowserListener* const newListener) throw() | void FileBrowserComponent::addListener (FileBrowserListener* const newListener) throw() | ||||
| { | { | ||||
| jassert (newListener != 0) | |||||
| if (newListener != 0) | |||||
| listeners.add (newListener); | |||||
| listeners.add (newListener); | |||||
| } | } | ||||
| void FileBrowserComponent::removeListener (FileBrowserListener* const listener) throw() | void FileBrowserComponent::removeListener (FileBrowserListener* const listener) throw() | ||||
| { | { | ||||
| listeners.removeValue (listener); | |||||
| listeners.remove (listener); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -302,23 +299,15 @@ void FileBrowserComponent::resized() | |||||
| //============================================================================== | //============================================================================== | ||||
| void FileBrowserComponent::sendListenerChangeMessage() | void FileBrowserComponent::sendListenerChangeMessage() | ||||
| { | { | ||||
| Component::SafePointer<Component> deletionWatcher (this); | |||||
| Component::BailOutChecker checker (this); | |||||
| if (previewComp != 0) | if (previewComp != 0) | ||||
| previewComp->selectedFileChanged (getSelectedFile (0)); | previewComp->selectedFileChanged (getSelectedFile (0)); | ||||
| // You shouldn't delete the browser when the file gets changed! | // You shouldn't delete the browser when the file gets changed! | ||||
| jassert (deletionWatcher != 0); | |||||
| for (int i = listeners.size(); --i >= 0;) | |||||
| { | |||||
| ((FileBrowserListener*) listeners.getUnchecked (i))->selectionChanged(); | |||||
| if (deletionWatcher == 0) | |||||
| return; | |||||
| jassert (! checker.shouldBailOut()); | |||||
| i = jmin (i, listeners.size() - 1); | |||||
| } | |||||
| listeners.callChecked (checker, &FileBrowserListener::selectionChanged); | |||||
| } | } | ||||
| void FileBrowserComponent::selectionChanged() | void FileBrowserComponent::selectionChanged() | ||||
| @@ -351,17 +340,8 @@ void FileBrowserComponent::selectionChanged() | |||||
| void FileBrowserComponent::fileClicked (const File& f, const MouseEvent& e) | void FileBrowserComponent::fileClicked (const File& f, const MouseEvent& e) | ||||
| { | { | ||||
| Component::SafePointer<Component> deletionWatcher (this); | |||||
| for (int i = listeners.size(); --i >= 0;) | |||||
| { | |||||
| ((FileBrowserListener*) listeners.getUnchecked (i))->fileClicked (f, e); | |||||
| if (deletionWatcher == 0) | |||||
| return; | |||||
| i = jmin (i, listeners.size() - 1); | |||||
| } | |||||
| Component::BailOutChecker checker (this); | |||||
| listeners.callChecked (checker, &FileBrowserListener::fileClicked, f, e); | |||||
| } | } | ||||
| void FileBrowserComponent::fileDoubleClicked (const File& f) | void FileBrowserComponent::fileDoubleClicked (const File& f) | ||||
| @@ -372,17 +352,8 @@ void FileBrowserComponent::fileDoubleClicked (const File& f) | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| Component::SafePointer<Component> deletionWatcher (this); | |||||
| for (int i = listeners.size(); --i >= 0;) | |||||
| { | |||||
| ((FileBrowserListener*) listeners.getUnchecked (i))->fileDoubleClicked (f); | |||||
| if (deletionWatcher == 0) | |||||
| return; | |||||
| i = jmin (i, listeners.size() - 1); | |||||
| } | |||||
| Component::BailOutChecker checker (this); | |||||
| listeners.callChecked (checker, &FileBrowserListener::fileDoubleClicked, f); | |||||
| } | } | ||||
| } | } | ||||
| @@ -213,7 +213,7 @@ private: | |||||
| int flags; | int flags; | ||||
| File currentRoot; | File currentRoot; | ||||
| Array<File> chosenFiles; | Array<File> chosenFiles; | ||||
| SortedSet <void*> listeners; | |||||
| ListenerList <FileBrowserListener> listeners; | |||||
| DirectoryContentsDisplayComponent* fileListComponent; | DirectoryContentsDisplayComponent* fileListComponent; | ||||
| FilePreviewComponent* previewComp; | FilePreviewComponent* previewComp; | ||||
| @@ -239,24 +239,18 @@ void FilenameComponent::addRecentlyUsedFile (const File& file) | |||||
| //============================================================================== | //============================================================================== | ||||
| void FilenameComponent::addListener (FilenameComponentListener* const listener) throw() | void FilenameComponent::addListener (FilenameComponentListener* const listener) throw() | ||||
| { | { | ||||
| jassert (listener != 0); | |||||
| if (listener != 0) | |||||
| listeners.add (listener); | |||||
| listeners.add (listener); | |||||
| } | } | ||||
| void FilenameComponent::removeListener (FilenameComponentListener* const listener) throw() | void FilenameComponent::removeListener (FilenameComponentListener* const listener) throw() | ||||
| { | { | ||||
| listeners.removeValue (listener); | |||||
| listeners.remove (listener); | |||||
| } | } | ||||
| void FilenameComponent::handleAsyncUpdate() | void FilenameComponent::handleAsyncUpdate() | ||||
| { | { | ||||
| for (int i = listeners.size(); --i >= 0;) | |||||
| { | |||||
| ((FilenameComponentListener*) listeners.getUnchecked (i))->filenameComponentChanged (this); | |||||
| i = jmin (i, listeners.size()); | |||||
| } | |||||
| Component::BailOutChecker checker (this); | |||||
| listeners.callChecked (checker, &FilenameComponentListener::filenameComponentChanged, this); | |||||
| } | } | ||||
| END_JUCE_NAMESPACE | END_JUCE_NAMESPACE | ||||
| @@ -209,7 +209,7 @@ private: | |||||
| int maxRecentFiles; | int maxRecentFiles; | ||||
| bool isDir, isSaving, isFileDragOver; | bool isDir, isSaving, isFileDragOver; | ||||
| String wildcard, enforcedSuffix, browseButtonText; | String wildcard, enforcedSuffix, browseButtonText; | ||||
| SortedSet <void*> listeners; | |||||
| ListenerList <FilenameComponentListener> listeners; | |||||
| File defaultBrowseFile; | File defaultBrowseFile; | ||||
| void comboBoxChanged (ComboBox*); | void comboBoxChanged (ComboBox*); | ||||
| @@ -36,6 +36,7 @@ | |||||
| #include "../graphics/geometry/juce_RectangleList.h" | #include "../graphics/geometry/juce_RectangleList.h" | ||||
| #include "../graphics/geometry/juce_BorderSize.h" | #include "../graphics/geometry/juce_BorderSize.h" | ||||
| #include "../../events/juce_MessageListener.h" | #include "../../events/juce_MessageListener.h" | ||||
| #include "../../events/juce_ListenerList.h" | |||||
| #include "../../text/juce_StringArray.h" | #include "../../text/juce_StringArray.h" | ||||
| #include "../../containers/juce_VoidArray.h" | #include "../../containers/juce_VoidArray.h" | ||||
| #include "../../containers/juce_NamedValueSet.h" | #include "../../containers/juce_NamedValueSet.h" | ||||
| @@ -1931,10 +1932,7 @@ public: | |||||
| } | } | ||||
| /** Returns the component that this pointer refers to, or null if the component no longer exists. */ | /** Returns the component that this pointer refers to, or null if the component no longer exists. */ | ||||
| operator ComponentType*() throw() { return comp; } | |||||
| /** Returns the component that this pointer refers to, or null if the component no longer exists. */ | |||||
| operator const ComponentType*() const throw() { return comp; } | |||||
| operator ComponentType*() const throw() { return comp; } | |||||
| /** Returns the component that this pointer refers to, or null if the component no longer exists. */ | /** Returns the component that this pointer refers to, or null if the component no longer exists. */ | ||||
| ComponentType* operator->() throw() { jassert (comp != 0); return comp; } | ComponentType* operator->() throw() { jassert (comp != 0); return comp; } | ||||
| @@ -1953,6 +1951,35 @@ public: | |||||
| void componentBeingDeleted (Component&) { comp = 0; } | void componentBeingDeleted (Component&) { comp = 0; } | ||||
| }; | }; | ||||
| //============================================================================== | |||||
| /** A class to keep an eye on one or two components and check for them being deleted. | |||||
| This is designed for use with the ListenerList::callChecked() methods, to allow | |||||
| the list iterator to stop cleanly if the component is deleted by a listener callback | |||||
| while the list is still being iterated. | |||||
| */ | |||||
| class BailOutChecker | |||||
| { | |||||
| public: | |||||
| /** Creates a checker that watches either one or two components. | |||||
| component1 must be a valid component; component2 can be null if you only need | |||||
| to check on one component. | |||||
| */ | |||||
| BailOutChecker (Component* const component1, | |||||
| Component* const component2 = 0); | |||||
| /** Returns true if either of the two components have been deleted since this | |||||
| object was created. */ | |||||
| bool shouldBailOut() const throw(); | |||||
| private: | |||||
| Component::SafePointer<Component> safePointer1, safePointer2; | |||||
| Component* const component2; | |||||
| BailOutChecker (const BailOutChecker&); | |||||
| BailOutChecker& operator= (const BailOutChecker&); | |||||
| }; | |||||
| //============================================================================== | //============================================================================== | ||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| @@ -1978,7 +2005,7 @@ private: | |||||
| Image* bufferedImage_; | Image* bufferedImage_; | ||||
| VoidArray* mouseListeners_; | VoidArray* mouseListeners_; | ||||
| VoidArray* keyListeners_; | VoidArray* keyListeners_; | ||||
| VoidArray* componentListeners_; | |||||
| ListenerList <ComponentListener> componentListeners; | |||||
| NamedValueSet properties; | NamedValueSet properties; | ||||
| struct ComponentFlags | struct ComponentFlags | ||||
| @@ -36,6 +36,6 @@ void ComponentListener::componentVisibilityChanged (Component&) {} | |||||
| void ComponentListener::componentChildrenChanged (Component&) {} | void ComponentListener::componentChildrenChanged (Component&) {} | ||||
| void ComponentListener::componentParentHierarchyChanged (Component&) {} | void ComponentListener::componentParentHierarchyChanged (Component&) {} | ||||
| void ComponentListener::componentNameChanged (Component&) {} | void ComponentListener::componentNameChanged (Component&) {} | ||||
| void ComponentListener::componentBeingDeleted (Component& component) {} | |||||
| void ComponentListener::componentBeingDeleted (Component&) {} | |||||
| END_JUCE_NAMESPACE | END_JUCE_NAMESPACE | ||||
| @@ -36,7 +36,7 @@ BEGIN_JUCE_NAMESPACE | |||||
| //============================================================================== | //============================================================================== | ||||
| Desktop::Desktop() throw() | |||||
| Desktop::Desktop() | |||||
| : mouseClickCounter (0), | : mouseClickCounter (0), | ||||
| kioskModeComponent (0) | kioskModeComponent (0) | ||||
| { | { | ||||
| @@ -44,7 +44,7 @@ Desktop::Desktop() throw() | |||||
| refreshMonitorSizes(); | refreshMonitorSizes(); | ||||
| } | } | ||||
| Desktop::~Desktop() throw() | |||||
| Desktop::~Desktop() | |||||
| { | { | ||||
| jassert (instance == this); | jassert (instance == this); | ||||
| instance = 0; | instance = 0; | ||||
| @@ -54,7 +54,7 @@ Desktop::~Desktop() throw() | |||||
| jassert (desktopComponents.size() == 0); | jassert (desktopComponents.size() == 0); | ||||
| } | } | ||||
| Desktop& JUCE_CALLTYPE Desktop::getInstance() throw() | |||||
| Desktop& JUCE_CALLTYPE Desktop::getInstance() | |||||
| { | { | ||||
| if (instance == 0) | if (instance == 0) | ||||
| instance = new Desktop(); | instance = new Desktop(); | ||||
| @@ -68,7 +68,7 @@ Desktop* Desktop::instance = 0; | |||||
| extern void juce_updateMultiMonitorInfo (Array <Rectangle<int> >& monitorCoords, | extern void juce_updateMultiMonitorInfo (Array <Rectangle<int> >& monitorCoords, | ||||
| const bool clipToWorkArea); | const bool clipToWorkArea); | ||||
| void Desktop::refreshMonitorSizes() throw() | |||||
| void Desktop::refreshMonitorSizes() | |||||
| { | { | ||||
| const Array <Rectangle<int> > oldClipped (monitorCoordsClipped); | const Array <Rectangle<int> > oldClipped (monitorCoordsClipped); | ||||
| const Array <Rectangle<int> > oldUnclipped (monitorCoordsUnclipped); | const Array <Rectangle<int> > oldUnclipped (monitorCoordsUnclipped); | ||||
| @@ -118,7 +118,7 @@ const Rectangle<int> Desktop::getMainMonitorArea (const bool clippedToWorkArea) | |||||
| return getDisplayMonitorCoordinates (0, clippedToWorkArea); | return getDisplayMonitorCoordinates (0, clippedToWorkArea); | ||||
| } | } | ||||
| const Rectangle<int> Desktop::getMonitorAreaContaining (const Point<int>& position, const bool clippedToWorkArea) const throw() | |||||
| const Rectangle<int> Desktop::getMonitorAreaContaining (const Point<int>& position, const bool clippedToWorkArea) const | |||||
| { | { | ||||
| Rectangle<int> best (getMainMonitorArea (clippedToWorkArea)); | Rectangle<int> best (getMainMonitorArea (clippedToWorkArea)); | ||||
| double bestDistance = 1.0e10; | double bestDistance = 1.0e10; | ||||
| @@ -168,19 +168,19 @@ Component* Desktop::findComponentAt (const Point<int>& screenPosition) const | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| void Desktop::addDesktopComponent (Component* const c) throw() | |||||
| void Desktop::addDesktopComponent (Component* const c) | |||||
| { | { | ||||
| jassert (c != 0); | jassert (c != 0); | ||||
| jassert (! desktopComponents.contains (c)); | jassert (! desktopComponents.contains (c)); | ||||
| desktopComponents.addIfNotAlreadyThere (c); | desktopComponents.addIfNotAlreadyThere (c); | ||||
| } | } | ||||
| void Desktop::removeDesktopComponent (Component* const c) throw() | |||||
| void Desktop::removeDesktopComponent (Component* const c) | |||||
| { | { | ||||
| desktopComponents.removeValue (c); | desktopComponents.removeValue (c); | ||||
| } | } | ||||
| void Desktop::componentBroughtToFront (Component* const c) throw() | |||||
| void Desktop::componentBroughtToFront (Component* const c) | |||||
| { | { | ||||
| const int index = desktopComponents.indexOf (c); | const int index = desktopComponents.indexOf (c); | ||||
| jassert (index >= 0); | jassert (index >= 0); | ||||
| @@ -249,52 +249,40 @@ MouseInputSource* Desktop::getDraggingMouseSource (int index) const throw() | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| void Desktop::addGlobalMouseListener (MouseListener* const listener) throw() | |||||
| void Desktop::addFocusChangeListener (FocusChangeListener* const listener) | |||||
| { | { | ||||
| jassert (listener != 0); | |||||
| if (listener != 0) | |||||
| { | |||||
| mouseListeners.add (listener); | |||||
| resetTimer(); | |||||
| } | |||||
| focusListeners.add (listener); | |||||
| } | } | ||||
| void Desktop::removeGlobalMouseListener (MouseListener* const listener) throw() | |||||
| void Desktop::removeFocusChangeListener (FocusChangeListener* const listener) | |||||
| { | { | ||||
| mouseListeners.removeValue (listener); | |||||
| resetTimer(); | |||||
| focusListeners.remove (listener); | |||||
| } | } | ||||
| //============================================================================== | |||||
| void Desktop::addFocusChangeListener (FocusChangeListener* const listener) throw() | |||||
| void Desktop::triggerFocusCallback() | |||||
| { | { | ||||
| jassert (listener != 0); | |||||
| if (listener != 0) | |||||
| focusListeners.add (listener); | |||||
| triggerAsyncUpdate(); | |||||
| } | } | ||||
| void Desktop::removeFocusChangeListener (FocusChangeListener* const listener) throw() | |||||
| void Desktop::handleAsyncUpdate() | |||||
| { | { | ||||
| focusListeners.removeValue (listener); | |||||
| Component* currentFocus = Component::getCurrentlyFocusedComponent(); | |||||
| focusListeners.call (&FocusChangeListener::globalFocusChanged, currentFocus); | |||||
| } | } | ||||
| void Desktop::triggerFocusCallback() throw() | |||||
| //============================================================================== | |||||
| void Desktop::addGlobalMouseListener (MouseListener* const listener) | |||||
| { | { | ||||
| triggerAsyncUpdate(); | |||||
| mouseListeners.add (listener); | |||||
| resetTimer(); | |||||
| } | } | ||||
| void Desktop::handleAsyncUpdate() | |||||
| void Desktop::removeGlobalMouseListener (MouseListener* const listener) | |||||
| { | { | ||||
| for (int i = focusListeners.size(); --i >= 0;) | |||||
| { | |||||
| ((FocusChangeListener*) focusListeners.getUnchecked (i))->globalFocusChanged (Component::getCurrentlyFocusedComponent()); | |||||
| i = jmin (i, focusListeners.size()); | |||||
| } | |||||
| mouseListeners.remove (listener); | |||||
| resetTimer(); | |||||
| } | } | ||||
| //============================================================================== | |||||
| void Desktop::timerCallback() | void Desktop::timerCallback() | ||||
| { | { | ||||
| if (lastFakeMouseMove != getMousePosition()) | if (lastFakeMouseMove != getMousePosition()) | ||||
| @@ -303,7 +291,7 @@ void Desktop::timerCallback() | |||||
| void Desktop::sendMouseMove() | void Desktop::sendMouseMove() | ||||
| { | { | ||||
| if (mouseListeners.size() > 0) | |||||
| if (! mouseListeners.isEmpty()) | |||||
| { | { | ||||
| startTimer (20); | startTimer (20); | ||||
| @@ -313,30 +301,22 @@ void Desktop::sendMouseMove() | |||||
| if (target != 0) | if (target != 0) | ||||
| { | { | ||||
| Component::SafePointer<Component> deletionChecker (target); | |||||
| Component::BailOutChecker checker (target); | |||||
| const Point<int> pos (target->globalPositionToRelative (lastFakeMouseMove)); | const Point<int> pos (target->globalPositionToRelative (lastFakeMouseMove)); | ||||
| const Time now (Time::getCurrentTime()); | const Time now (Time::getCurrentTime()); | ||||
| const MouseEvent me (getMainMouseSource(), pos, ModifierKeys::getCurrentModifiers(), | const MouseEvent me (getMainMouseSource(), pos, ModifierKeys::getCurrentModifiers(), | ||||
| target, now, pos, now, 0, false); | target, now, pos, now, 0, false); | ||||
| for (int i = mouseListeners.size(); --i >= 0;) | |||||
| { | |||||
| if (ModifierKeys::getCurrentModifiers().isAnyMouseButtonDown()) | |||||
| ((MouseListener*) mouseListeners[i])->mouseDrag (me); | |||||
| else | |||||
| ((MouseListener*) mouseListeners[i])->mouseMove (me); | |||||
| if (deletionChecker == 0) | |||||
| return; | |||||
| i = jmin (i, mouseListeners.size()); | |||||
| } | |||||
| if (me.mods.isAnyMouseButtonDown()) | |||||
| mouseListeners.callChecked (checker, &MouseListener::mouseDrag, me); | |||||
| else | |||||
| mouseListeners.callChecked (checker, &MouseListener::mouseMove, me); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void Desktop::resetTimer() throw() | |||||
| void Desktop::resetTimer() | |||||
| { | { | ||||
| if (mouseListeners.size() == 0) | if (mouseListeners.size() == 0) | ||||
| stopTimer(); | stopTimer(); | ||||
| @@ -31,7 +31,6 @@ | |||||
| #include "../../utilities/juce_DeletedAtShutdown.h" | #include "../../utilities/juce_DeletedAtShutdown.h" | ||||
| #include "../../events/juce_Timer.h" | #include "../../events/juce_Timer.h" | ||||
| #include "../../events/juce_AsyncUpdater.h" | #include "../../events/juce_AsyncUpdater.h" | ||||
| #include "../../containers/juce_SortedSet.h" | |||||
| #include "../../containers/juce_OwnedArray.h" | #include "../../containers/juce_OwnedArray.h" | ||||
| #include "../graphics/geometry/juce_RectangleList.h" | #include "../graphics/geometry/juce_RectangleList.h" | ||||
| class MouseInputSource; | class MouseInputSource; | ||||
| @@ -70,7 +69,7 @@ public: | |||||
| //============================================================================== | //============================================================================== | ||||
| /** There's only one dektop object, and this method will return it. | /** There's only one dektop object, and this method will return it. | ||||
| */ | */ | ||||
| static Desktop& JUCE_CALLTYPE getInstance() throw(); | |||||
| static Desktop& JUCE_CALLTYPE getInstance(); | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Returns a list of the positions of all the monitors available. | /** Returns a list of the positions of all the monitors available. | ||||
| @@ -97,7 +96,7 @@ public: | |||||
| If clippedToWorkArea is true, it will exclude any areas like the taskbar on Windows, | If clippedToWorkArea is true, it will exclude any areas like the taskbar on Windows, | ||||
| or the menu bar on Mac. If clippedToWorkArea is false, the entire monitor area is returned. | or the menu bar on Mac. If clippedToWorkArea is false, the entire monitor area is returned. | ||||
| */ | */ | ||||
| const Rectangle<int> getMonitorAreaContaining (const Point<int>& position, const bool clippedToWorkArea = true) const throw(); | |||||
| const Rectangle<int> getMonitorAreaContaining (const Point<int>& position, const bool clippedToWorkArea = true) const; | |||||
| //============================================================================== | //============================================================================== | ||||
| @@ -157,23 +156,23 @@ public: | |||||
| @see removeGlobalMouseListener | @see removeGlobalMouseListener | ||||
| */ | */ | ||||
| void addGlobalMouseListener (MouseListener* const listener) throw(); | |||||
| void addGlobalMouseListener (MouseListener* const listener); | |||||
| /** Unregisters a MouseListener that was added with the addGlobalMouseListener() | /** Unregisters a MouseListener that was added with the addGlobalMouseListener() | ||||
| method. | method. | ||||
| @see addGlobalMouseListener | @see addGlobalMouseListener | ||||
| */ | */ | ||||
| void removeGlobalMouseListener (MouseListener* const listener) throw(); | |||||
| void removeGlobalMouseListener (MouseListener* const listener); | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Registers a MouseListener that will receive a callback whenever the focused | /** Registers a MouseListener that will receive a callback whenever the focused | ||||
| component changes. | component changes. | ||||
| */ | */ | ||||
| void addFocusChangeListener (FocusChangeListener* const listener) throw(); | |||||
| void addFocusChangeListener (FocusChangeListener* const listener); | |||||
| /** Unregisters a listener that was added with addFocusChangeListener(). */ | /** Unregisters a listener that was added with addFocusChangeListener(). */ | ||||
| void removeFocusChangeListener (FocusChangeListener* const listener) throw(); | |||||
| void removeFocusChangeListener (FocusChangeListener* const listener); | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Takes a component and makes it full-screen, removing the taskbar, dock, etc. | /** Takes a component and makes it full-screen, removing the taskbar, dock, etc. | ||||
| @@ -198,7 +197,7 @@ public: | |||||
| This is the component that was last set by setKioskModeComponent(). If none | This is the component that was last set by setKioskModeComponent(). If none | ||||
| has been set, this returns 0. | has been set, this returns 0. | ||||
| */ | */ | ||||
| Component* getKioskModeComponent() const { return kioskModeComponent; } | |||||
| Component* getKioskModeComponent() const throw() { return kioskModeComponent; } | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Returns the number of components that are currently active as top-level | /** Returns the number of components that are currently active as top-level | ||||
| @@ -269,7 +268,7 @@ public: | |||||
| (Called internally by the native code). | (Called internally by the native code). | ||||
| */ | */ | ||||
| void refreshMonitorSizes() throw(); | |||||
| void refreshMonitorSizes(); | |||||
| /** True if the OS supports semitransparent windows */ | /** True if the OS supports semitransparent windows */ | ||||
| static bool canUseSemiTransparentWindows() throw(); | static bool canUseSemiTransparentWindows() throw(); | ||||
| @@ -282,42 +281,43 @@ private: | |||||
| friend class ComponentPeer; | friend class ComponentPeer; | ||||
| friend class MouseInputSource; | friend class MouseInputSource; | ||||
| friend class MouseInputSourceInternal; | friend class MouseInputSourceInternal; | ||||
| SortedSet <void*> mouseListeners, focusListeners; | |||||
| Array <Component*> desktopComponents; | |||||
| friend class DeletedAtShutdown; | friend class DeletedAtShutdown; | ||||
| friend class TopLevelWindowManager; | friend class TopLevelWindowManager; | ||||
| Desktop() throw(); | |||||
| ~Desktop() throw(); | |||||
| Array <Rectangle<int> > monitorCoordsClipped, monitorCoordsUnclipped; | |||||
| OwnedArray <MouseInputSource> mouseSources; | OwnedArray <MouseInputSource> mouseSources; | ||||
| void createMouseInputSources(); | |||||
| ListenerList <MouseListener> mouseListeners; | |||||
| ListenerList <FocusChangeListener> focusListeners; | |||||
| Array <Component*> desktopComponents; | |||||
| Array <Rectangle<int> > monitorCoordsClipped, monitorCoordsUnclipped; | |||||
| Point<int> lastFakeMouseMove; | Point<int> lastFakeMouseMove; | ||||
| int mouseClickCounter; | |||||
| void sendMouseMove(); | |||||
| int mouseClickCounter; | |||||
| void incrementMouseClickCounter() throw(); | void incrementMouseClickCounter() throw(); | ||||
| Component* kioskModeComponent; | Component* kioskModeComponent; | ||||
| Rectangle<int> kioskComponentOriginalBounds; | Rectangle<int> kioskComponentOriginalBounds; | ||||
| void createMouseInputSources(); | |||||
| void timerCallback(); | void timerCallback(); | ||||
| void sendMouseMove(); | |||||
| void resetTimer() throw(); | |||||
| void resetTimer(); | |||||
| int getNumDisplayMonitors() const throw(); | int getNumDisplayMonitors() const throw(); | ||||
| const Rectangle<int> getDisplayMonitorCoordinates (const int index, const bool clippedToWorkArea) const throw(); | const Rectangle<int> getDisplayMonitorCoordinates (const int index, const bool clippedToWorkArea) const throw(); | ||||
| void addDesktopComponent (Component* const c) throw(); | |||||
| void removeDesktopComponent (Component* const c) throw(); | |||||
| void componentBroughtToFront (Component* const c) throw(); | |||||
| void addDesktopComponent (Component* const c); | |||||
| void removeDesktopComponent (Component* const c); | |||||
| void componentBroughtToFront (Component* const c); | |||||
| void triggerFocusCallback() throw(); | |||||
| void triggerFocusCallback(); | |||||
| void handleAsyncUpdate(); | void handleAsyncUpdate(); | ||||
| Desktop(); | |||||
| ~Desktop(); | |||||
| Desktop (const Desktop&); | Desktop (const Desktop&); | ||||
| Desktop& operator= (const Desktop&); | Desktop& operator= (const Desktop&); | ||||
| }; | }; | ||||
| @@ -189,25 +189,17 @@ void ScrollBar::setButtonRepeatSpeed (const int initialDelayInMillisecs_, | |||||
| //============================================================================== | //============================================================================== | ||||
| void ScrollBar::addListener (ScrollBarListener* const listener) throw() | void ScrollBar::addListener (ScrollBarListener* const listener) throw() | ||||
| { | { | ||||
| jassert (listener != 0); | |||||
| if (listener != 0) | |||||
| listeners.add (listener); | |||||
| listeners.add (listener); | |||||
| } | } | ||||
| void ScrollBar::removeListener (ScrollBarListener* const listener) throw() | void ScrollBar::removeListener (ScrollBarListener* const listener) throw() | ||||
| { | { | ||||
| listeners.removeValue (listener); | |||||
| listeners.remove (listener); | |||||
| } | } | ||||
| void ScrollBar::handleAsyncUpdate() | void ScrollBar::handleAsyncUpdate() | ||||
| { | { | ||||
| const double value = getCurrentRangeStart(); | |||||
| for (int i = listeners.size(); --i >= 0;) | |||||
| { | |||||
| ((ScrollBarListener*) listeners.getUnchecked (i))->scrollBarMoved (this, value); | |||||
| i = jmin (i, listeners.size()); | |||||
| } | |||||
| listeners.call (&ScrollBarListener::scrollBarMoved, this, rangeStart); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -293,7 +293,7 @@ private: | |||||
| bool vertical, isDraggingThumb, alwaysVisible; | bool vertical, isDraggingThumb, alwaysVisible; | ||||
| Button* upButton; | Button* upButton; | ||||
| Button* downButton; | Button* downButton; | ||||
| SortedSet <void*> listeners; | |||||
| ListenerList <ScrollBarListener> listeners; | |||||
| void updateThumbPosition() throw(); | void updateThumbPosition() throw(); | ||||
| void timerCallback(); | void timerCallback(); | ||||
| @@ -63,11 +63,7 @@ void MenuBarModel::setApplicationCommandManagerToWatch (ApplicationCommandManage | |||||
| void MenuBarModel::addListener (MenuBarModelListener* const newListener) throw() | void MenuBarModel::addListener (MenuBarModelListener* const newListener) throw() | ||||
| { | { | ||||
| jassert (newListener != 0); | |||||
| jassert (! listeners.contains (newListener)); // trying to add a listener to the list twice! | |||||
| if (newListener != 0) | |||||
| listeners.add (newListener); | |||||
| listeners.add (newListener); | |||||
| } | } | ||||
| void MenuBarModel::removeListener (MenuBarModelListener* const listenerToRemove) throw() | void MenuBarModel::removeListener (MenuBarModelListener* const listenerToRemove) throw() | ||||
| @@ -77,26 +73,18 @@ void MenuBarModel::removeListener (MenuBarModelListener* const listenerToRemove) | |||||
| // deleted this menu model while it's still being used by something (e.g. by a MenuBarComponent) | // deleted this menu model while it's still being used by something (e.g. by a MenuBarComponent) | ||||
| jassert (listeners.contains (listenerToRemove)); | jassert (listeners.contains (listenerToRemove)); | ||||
| listeners.removeValue (listenerToRemove); | |||||
| listeners.remove (listenerToRemove); | |||||
| } | } | ||||
| //============================================================================== | |||||
| void MenuBarModel::handleAsyncUpdate() | void MenuBarModel::handleAsyncUpdate() | ||||
| { | { | ||||
| for (int i = listeners.size(); --i >= 0;) | |||||
| { | |||||
| ((MenuBarModelListener*) listeners.getUnchecked (i))->menuBarItemsChanged (this); | |||||
| i = jmin (i, listeners.size()); | |||||
| } | |||||
| listeners.call (&MenuBarModelListener::menuBarItemsChanged, this); | |||||
| } | } | ||||
| //============================================================================== | |||||
| void MenuBarModel::applicationCommandInvoked (const ApplicationCommandTarget::InvocationInfo& info) | void MenuBarModel::applicationCommandInvoked (const ApplicationCommandTarget::InvocationInfo& info) | ||||
| { | { | ||||
| for (int i = listeners.size(); --i >= 0;) | |||||
| { | |||||
| ((MenuBarModelListener*) listeners.getUnchecked (i))->menuCommandInvoked (this, info); | |||||
| i = jmin (i, listeners.size()); | |||||
| } | |||||
| listeners.call (&MenuBarModelListener::menuCommandInvoked, this, info); | |||||
| } | } | ||||
| void MenuBarModel::applicationCommandListChanged() | void MenuBarModel::applicationCommandListChanged() | ||||
| @@ -172,7 +172,7 @@ public: | |||||
| private: | private: | ||||
| ApplicationCommandManager* manager; | ApplicationCommandManager* manager; | ||||
| SortedSet <void*> listeners; | |||||
| ListenerList <MenuBarModelListener> listeners; | |||||
| MenuBarModel (const MenuBarModel&); | MenuBarModel (const MenuBarModel&); | ||||
| MenuBarModel& operator= (const MenuBarModel&); | MenuBarModel& operator= (const MenuBarModel&); | ||||
| @@ -351,6 +351,7 @@ public: | |||||
| mw->menuBarComponent = menuBarComponent; | mw->menuBarComponent = menuBarComponent; | ||||
| mw->managerOfChosenCommand = managerOfChosenCommand; | mw->managerOfChosenCommand = managerOfChosenCommand; | ||||
| mw->componentAttachedTo = componentAttachedTo; | mw->componentAttachedTo = componentAttachedTo; | ||||
| mw->componentAttachedToOriginal = componentAttachedTo; | |||||
| mw->calculateWindowPos (minX, maxX, minY, maxY, alignToRectangle); | mw->calculateWindowPos (minX, maxX, minY, maxY, alignToRectangle); | ||||
| mw->setTopLeftPosition (mw->windowPos.getX(), | mw->setTopLeftPosition (mw->windowPos.getX(), | ||||
| @@ -502,16 +503,14 @@ public: | |||||
| } | } | ||||
| else if (key.isKeyCode (KeyPress::leftKey)) | else if (key.isKeyCode (KeyPress::leftKey)) | ||||
| { | { | ||||
| Window* parentWindow = owner; | |||||
| if (parentWindow != 0) | |||||
| if (owner != 0) | |||||
| { | { | ||||
| PopupMenu::ItemComponent* currentChildOfParent | |||||
| = (parentWindow != 0) ? parentWindow->currentChild : 0; | |||||
| Component::SafePointer<Window> parentWindow (owner); | |||||
| PopupMenu::ItemComponent* currentChildOfParent = parentWindow->currentChild; | |||||
| hide (0); | hide (0); | ||||
| if (parentWindow->isValidComponent()) | |||||
| if (parentWindow != 0) | |||||
| parentWindow->setCurrentlyHighlightedChild (currentChildOfParent); | parentWindow->setCurrentlyHighlightedChild (currentChildOfParent); | ||||
| disableTimerUntilMouseMoves(); | disableTimerUntilMouseMoves(); | ||||
| @@ -594,7 +593,7 @@ public: | |||||
| if (! isVisible()) | if (! isVisible()) | ||||
| return; | return; | ||||
| if (componentAttachedTo == 0) | |||||
| if (componentAttachedTo != componentAttachedToOriginal) | |||||
| { | { | ||||
| dismissMenu (0); | dismissMenu (0); | ||||
| return; | return; | ||||
| @@ -748,6 +747,7 @@ private: | |||||
| Component* menuBarComponent; | Component* menuBarComponent; | ||||
| ApplicationCommandManager** managerOfChosenCommand; | ApplicationCommandManager** managerOfChosenCommand; | ||||
| Component::SafePointer<Component> componentAttachedTo; | Component::SafePointer<Component> componentAttachedTo; | ||||
| Component* componentAttachedToOriginal; | |||||
| Rectangle<int> windowPos; | Rectangle<int> windowPos; | ||||
| Point<int> lastMouse; | Point<int> lastMouse; | ||||
| int minimumWidth, maximumNumColumns, standardItemHeight; | int minimumWidth, maximumNumColumns, standardItemHeight; | ||||
| @@ -254,6 +254,9 @@ | |||||
| #ifndef __JUCE_INTERPROCESSCONNECTIONSERVER_JUCEHEADER__ | #ifndef __JUCE_INTERPROCESSCONNECTIONSERVER_JUCEHEADER__ | ||||
| #include "events/juce_InterprocessConnectionServer.h" | #include "events/juce_InterprocessConnectionServer.h" | ||||
| #endif | #endif | ||||
| #ifndef __JUCE_LISTENERLIST_JUCEHEADER__ | |||||
| #include "events/juce_ListenerList.h" | |||||
| #endif | |||||
| #ifndef __JUCE_MESSAGE_JUCEHEADER__ | #ifndef __JUCE_MESSAGE_JUCEHEADER__ | ||||
| #include "events/juce_Message.h" | #include "events/juce_Message.h" | ||||
| #endif | #endif | ||||
| @@ -509,6 +512,9 @@ | |||||
| #ifndef __JUCE_MOUSEHOVERDETECTOR_JUCEHEADER__ | #ifndef __JUCE_MOUSEHOVERDETECTOR_JUCEHEADER__ | ||||
| #include "gui/components/mouse/juce_MouseHoverDetector.h" | #include "gui/components/mouse/juce_MouseHoverDetector.h" | ||||
| #endif | #endif | ||||
| #ifndef __JUCE_MOUSEINPUTSOURCE_JUCEHEADER__ | |||||
| #include "gui/components/mouse/juce_MouseInputSource.h" | |||||
| #endif | |||||
| #ifndef __JUCE_MOUSELISTENER_JUCEHEADER__ | #ifndef __JUCE_MOUSELISTENER_JUCEHEADER__ | ||||
| #include "gui/components/mouse/juce_MouseListener.h" | #include "gui/components/mouse/juce_MouseListener.h" | ||||
| #endif | #endif | ||||
| @@ -73,6 +73,7 @@ BEGIN_JUCE_NAMESPACE | |||||
| #include "../gui/components/windows/juce_AlertWindow.h" | #include "../gui/components/windows/juce_AlertWindow.h" | ||||
| #include "../gui/components/special/juce_OpenGLComponent.h" | #include "../gui/components/special/juce_OpenGLComponent.h" | ||||
| #include "../gui/components/juce_Desktop.h" | #include "../gui/components/juce_Desktop.h" | ||||
| #include "../gui/components/mouse/juce_MouseInputSource.h" | |||||
| #include "../gui/graphics/geometry/juce_RectangleList.h" | #include "../gui/graphics/geometry/juce_RectangleList.h" | ||||
| #include "../gui/graphics/imaging/juce_ImageFileFormat.h" | #include "../gui/graphics/imaging/juce_ImageFileFormat.h" | ||||
| #include "../gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h" | #include "../gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h" | ||||
| @@ -64,6 +64,7 @@ BEGIN_JUCE_NAMESPACE | |||||
| #include "../gui/components/special/juce_OpenGLComponent.h" | #include "../gui/components/special/juce_OpenGLComponent.h" | ||||
| #include "../gui/components/special/juce_QuickTimeMovieComponent.h" | #include "../gui/components/special/juce_QuickTimeMovieComponent.h" | ||||
| #include "../gui/components/mouse/juce_DragAndDropContainer.h" | #include "../gui/components/mouse/juce_DragAndDropContainer.h" | ||||
| #include "../gui/components/mouse/juce_MouseInputSource.h" | |||||
| #include "../gui/components/keyboard/juce_KeyPressMappingSet.h" | #include "../gui/components/keyboard/juce_KeyPressMappingSet.h" | ||||
| #include "../gui/components/layout/juce_ComponentMovementWatcher.h" | #include "../gui/components/layout/juce_ComponentMovementWatcher.h" | ||||
| #include "../gui/components/special/juce_ActiveXControlComponent.h" | #include "../gui/components/special/juce_ActiveXControlComponent.h" | ||||
| @@ -1312,7 +1312,7 @@ private: | |||||
| { | { | ||||
| updateKeyModifiers(); | updateKeyModifiers(); | ||||
| const float amount = jlimit (-1000.0f, 1000.0f, 0.75f * HIWORD (wParam)); | |||||
| const float amount = jlimit (-1000.0f, 1000.0f, 0.75f * (short) HIWORD (wParam)); | |||||
| handleMouseWheel (0, position, getMouseEventTime(), | handleMouseWheel (0, position, getMouseEventTime(), | ||||
| isVertical ? 0.0f : amount, | isVertical ? 0.0f : amount, | ||||