| @@ -288,6 +288,7 @@ | |||||
| #include "../src/gui/components/mouse/juce_DragAndDropContainer.cpp" | #include "../src/gui/components/mouse/juce_DragAndDropContainer.cpp" | ||||
| #include "../src/gui/components/mouse/juce_MouseCursor.cpp" | #include "../src/gui/components/mouse/juce_MouseCursor.cpp" | ||||
| #include "../src/gui/components/mouse/juce_MouseEvent.cpp" | #include "../src/gui/components/mouse/juce_MouseEvent.cpp" | ||||
| #include "../src/gui/components/mouse/juce_MouseInputSource.cpp" | |||||
| #include "../src/gui/components/mouse/juce_MouseHoverDetector.cpp" | #include "../src/gui/components/mouse/juce_MouseHoverDetector.cpp" | ||||
| #include "../src/gui/components/mouse/juce_MouseListener.cpp" | #include "../src/gui/components/mouse/juce_MouseListener.cpp" | ||||
| #include "../src/gui/components/properties/juce_BooleanPropertyComponent.cpp" | #include "../src/gui/components/properties/juce_BooleanPropertyComponent.cpp" | ||||
| @@ -34,6 +34,8 @@ | |||||
| 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 */; }; | ||||
| 8473E6541125974600D74E02 /* juce_Range.h in Headers */ = {isa = PBXBuildFile; fileRef = 8473E6521125974600D74E02 /* juce_Range.h */; }; | 8473E6541125974600D74E02 /* juce_Range.h in Headers */ = {isa = PBXBuildFile; fileRef = 8473E6521125974600D74E02 /* juce_Range.h */; }; | ||||
| 84751E5B1132EE9E00640F9A /* juce_MouseInputSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84751E591132EE9E00640F9A /* juce_MouseInputSource.cpp */; }; | |||||
| 84751E5C1132EE9E00640F9A /* juce_MouseInputSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84751E5A1132EE9E00640F9A /* juce_MouseInputSource.h */; }; | |||||
| 84816E5710809D07008FEC33 /* juce_iphone_Audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84816E5110809D07008FEC33 /* juce_iphone_Audio.cpp */; }; | 84816E5710809D07008FEC33 /* juce_iphone_Audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84816E5110809D07008FEC33 /* juce_iphone_Audio.cpp */; }; | ||||
| 84816E5910809D07008FEC33 /* juce_iphone_MessageManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84816E5310809D07008FEC33 /* juce_iphone_MessageManager.mm */; }; | 84816E5910809D07008FEC33 /* juce_iphone_MessageManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84816E5310809D07008FEC33 /* juce_iphone_MessageManager.mm */; }; | ||||
| 84816E5A10809D07008FEC33 /* juce_iphone_MiscUtilities.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84816E5410809D07008FEC33 /* juce_iphone_MiscUtilities.mm */; }; | 84816E5A10809D07008FEC33 /* juce_iphone_MiscUtilities.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84816E5410809D07008FEC33 /* juce_iphone_MiscUtilities.mm */; }; | ||||
| @@ -1243,6 +1245,8 @@ | |||||
| 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; }; | ||||
| 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>"; }; | |||||
| 84751E5A1132EE9E00640F9A /* juce_MouseInputSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = juce_MouseInputSource.h; sourceTree = "<group>"; }; | |||||
| 84816E3510809B4F008FEC33 /* libjucedebug.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjucedebug.a; sourceTree = BUILT_PRODUCTS_DIR; }; | 84816E3510809B4F008FEC33 /* libjucedebug.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjucedebug.a; sourceTree = BUILT_PRODUCTS_DIR; }; | ||||
| 84816E5110809D07008FEC33 /* juce_iphone_Audio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = juce_iphone_Audio.cpp; sourceTree = "<group>"; }; | 84816E5110809D07008FEC33 /* juce_iphone_Audio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = juce_iphone_Audio.cpp; sourceTree = "<group>"; }; | ||||
| 84816E5310809D07008FEC33 /* juce_iphone_MessageManager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = juce_iphone_MessageManager.mm; sourceTree = "<group>"; }; | 84816E5310809D07008FEC33 /* juce_iphone_MessageManager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = juce_iphone_MessageManager.mm; sourceTree = "<group>"; }; | ||||
| @@ -2674,6 +2678,8 @@ | |||||
| 84F1EAD810403709006A1807 /* juce_MouseEvent.cpp */, | 84F1EAD810403709006A1807 /* juce_MouseEvent.cpp */, | ||||
| 84F1EAD910403709006A1807 /* juce_MouseHoverDetector.h */, | 84F1EAD910403709006A1807 /* juce_MouseHoverDetector.h */, | ||||
| 84F1EADA10403709006A1807 /* juce_MouseHoverDetector.cpp */, | 84F1EADA10403709006A1807 /* juce_MouseHoverDetector.cpp */, | ||||
| 84751E591132EE9E00640F9A /* juce_MouseInputSource.cpp */, | |||||
| 84751E5A1132EE9E00640F9A /* juce_MouseInputSource.h */, | |||||
| 84F1EADB10403709006A1807 /* juce_MouseListener.h */, | 84F1EADB10403709006A1807 /* juce_MouseListener.h */, | ||||
| 84F1EADC10403709006A1807 /* juce_MouseListener.cpp */, | 84F1EADC10403709006A1807 /* juce_MouseListener.cpp */, | ||||
| 84F1EADD10403709006A1807 /* juce_TooltipClient.h */, | 84F1EADD10403709006A1807 /* juce_TooltipClient.h */, | ||||
| @@ -3584,6 +3590,7 @@ | |||||
| 8414DE8511122A8D00DAF75A /* juce_DynamicObject.h in Headers */, | 8414DE8511122A8D00DAF75A /* juce_DynamicObject.h in Headers */, | ||||
| 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 */, | |||||
| ); | ); | ||||
| runOnlyForDeploymentPostprocessing = 0; | runOnlyForDeploymentPostprocessing = 0; | ||||
| }; | }; | ||||
| @@ -4226,6 +4233,7 @@ | |||||
| 84CABF691101292D0088D64D /* juce_TemporaryFile.cpp in Sources */, | 84CABF691101292D0088D64D /* juce_TemporaryFile.cpp in Sources */, | ||||
| 8414DE78111229B300DAF75A /* juce_NamedValueSet.cpp in Sources */, | 8414DE78111229B300DAF75A /* juce_NamedValueSet.cpp in Sources */, | ||||
| 8414DE8411122A8D00DAF75A /* juce_DynamicObject.cpp in Sources */, | 8414DE8411122A8D00DAF75A /* juce_DynamicObject.cpp in Sources */, | ||||
| 84751E5B1132EE9E00640F9A /* juce_MouseInputSource.cpp in Sources */, | |||||
| ); | ); | ||||
| runOnlyForDeploymentPostprocessing = 0; | runOnlyForDeploymentPostprocessing = 0; | ||||
| }; | }; | ||||
| @@ -1931,6 +1931,14 @@ | |||||
| RelativePath="..\..\..\src\gui\components\mouse\juce_MouseHoverDetector.h" | RelativePath="..\..\..\src\gui\components\mouse\juce_MouseHoverDetector.h" | ||||
| > | > | ||||
| </File> | </File> | ||||
| <File | |||||
| RelativePath="..\..\..\src\gui\components\mouse\juce_MouseInputSource.cpp" | |||||
| > | |||||
| </File> | |||||
| <File | |||||
| RelativePath="..\..\..\src\gui\components\mouse\juce_MouseInputSource.h" | |||||
| > | |||||
| </File> | |||||
| <File | <File | ||||
| RelativePath="..\..\..\src\gui\components\mouse\juce_MouseListener.cpp" | RelativePath="..\..\..\src\gui\components\mouse\juce_MouseListener.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 2 | |||||
| #define JUCE_BUILDNUMBER 3 | |||||
| #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) | ||||
| @@ -1385,41 +1385,41 @@ private: | |||||
| void dupeInternalIfMultiplyReferenced() throw(); | void dupeInternalIfMultiplyReferenced() throw(); | ||||
| }; | }; | ||||
| const String JUCE_PUBLIC_FUNCTION operator+ (const char* string1, const String& string2); | |||||
| const String JUCE_PUBLIC_FUNCTION operator+ (const juce_wchar* string1, const String& string2); | |||||
| const String JUCE_PUBLIC_FUNCTION operator+ (char string1, const String& string2); | |||||
| const String JUCE_PUBLIC_FUNCTION operator+ (juce_wchar string1, const String& string2); | |||||
| const String JUCE_PUBLIC_FUNCTION operator+ (String string1, const String& string2); | |||||
| const String JUCE_PUBLIC_FUNCTION operator+ (String string1, const char* string2); | |||||
| const String JUCE_PUBLIC_FUNCTION operator+ (String string1, const juce_wchar* string2); | |||||
| const String JUCE_PUBLIC_FUNCTION operator+ (String string1, char characterToAppend); | |||||
| const String JUCE_PUBLIC_FUNCTION operator+ (String string1, juce_wchar characterToAppend); | |||||
| String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const char characterToAppend); | |||||
| String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const juce_wchar characterToAppend); | |||||
| String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const char* const string2); | |||||
| String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const juce_wchar* const string2); | |||||
| String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const String& string2); | |||||
| String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const short number); | |||||
| String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const int number); | |||||
| String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const unsigned int number); | |||||
| String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const long number); | |||||
| String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const unsigned long number); | |||||
| String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const float number); | |||||
| String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const double number); | |||||
| bool JUCE_PUBLIC_FUNCTION operator== (const String& string1, const String& string2) throw(); | |||||
| bool JUCE_PUBLIC_FUNCTION operator== (const String& string1, const char* string2) throw(); | |||||
| bool JUCE_PUBLIC_FUNCTION operator== (const String& string1, const juce_wchar* string2) throw(); | |||||
| bool JUCE_PUBLIC_FUNCTION operator!= (const String& string1, const String& string2) throw(); | |||||
| bool JUCE_PUBLIC_FUNCTION operator!= (const String& string1, const char* string2) throw(); | |||||
| bool JUCE_PUBLIC_FUNCTION operator!= (const String& string1, const juce_wchar* string2) throw(); | |||||
| bool JUCE_PUBLIC_FUNCTION operator> (const String& string1, const String& string2) throw(); | |||||
| bool JUCE_PUBLIC_FUNCTION operator< (const String& string1, const String& string2) throw(); | |||||
| bool JUCE_PUBLIC_FUNCTION operator>= (const String& string1, const String& string2) throw(); | |||||
| bool JUCE_PUBLIC_FUNCTION operator<= (const String& string1, const String& string2) throw(); | |||||
| const String operator+ (const char* string1, const String& string2); | |||||
| const String operator+ (const juce_wchar* string1, const String& string2); | |||||
| const String operator+ (char string1, const String& string2); | |||||
| const String operator+ (juce_wchar string1, const String& string2); | |||||
| const String operator+ (String string1, const String& string2); | |||||
| const String operator+ (String string1, const char* string2); | |||||
| const String operator+ (String string1, const juce_wchar* string2); | |||||
| const String operator+ (String string1, char characterToAppend); | |||||
| const String operator+ (String string1, juce_wchar characterToAppend); | |||||
| String& operator<< (String& string1, const char characterToAppend); | |||||
| String& operator<< (String& string1, const juce_wchar characterToAppend); | |||||
| String& operator<< (String& string1, const char* const string2); | |||||
| String& operator<< (String& string1, const juce_wchar* const string2); | |||||
| String& operator<< (String& string1, const String& string2); | |||||
| String& operator<< (String& string1, const short number); | |||||
| String& operator<< (String& string1, const int number); | |||||
| String& operator<< (String& string1, const unsigned int number); | |||||
| String& operator<< (String& string1, const long number); | |||||
| String& operator<< (String& string1, const unsigned long number); | |||||
| String& operator<< (String& string1, const float number); | |||||
| String& operator<< (String& string1, const double number); | |||||
| bool operator== (const String& string1, const String& string2) throw(); | |||||
| bool operator== (const String& string1, const char* string2) throw(); | |||||
| bool operator== (const String& string1, const juce_wchar* string2) throw(); | |||||
| bool operator!= (const String& string1, const String& string2) throw(); | |||||
| bool operator!= (const String& string1, const char* string2) throw(); | |||||
| bool operator!= (const String& string1, const juce_wchar* string2) throw(); | |||||
| bool operator> (const String& string1, const String& string2) throw(); | |||||
| bool operator< (const String& string1, const String& string2) throw(); | |||||
| bool operator>= (const String& string1, const String& string2) throw(); | |||||
| bool operator<= (const String& string1, const String& string2) throw(); | |||||
| template <class charT, class traits> | template <class charT, class traits> | ||||
| std::basic_ostream <charT, traits>& operator<< (std::basic_ostream <charT, traits>& stream, const String& stringToWrite) | std::basic_ostream <charT, traits>& operator<< (std::basic_ostream <charT, traits>& stream, const String& stringToWrite) | ||||
| @@ -1427,7 +1427,7 @@ std::basic_ostream <charT, traits>& operator<< (std::basic_ostream <charT, trait | |||||
| return stream << stringToWrite.toUTF8(); | return stream << stringToWrite.toUTF8(); | ||||
| } | } | ||||
| OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const String& text); | |||||
| OutputStream& operator<< (OutputStream& stream, const String& text); | |||||
| #endif // __JUCE_STRING_JUCEHEADER__ | #endif // __JUCE_STRING_JUCEHEADER__ | ||||
| /*** End of inlined file: juce_String.h ***/ | /*** End of inlined file: juce_String.h ***/ | ||||
| @@ -2850,13 +2850,13 @@ public: | |||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| }; | }; | ||||
| OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const int number); | |||||
| OutputStream& operator<< (OutputStream& stream, const int number); | |||||
| OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const double number); | |||||
| OutputStream& operator<< (OutputStream& stream, const double number); | |||||
| OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const char character); | |||||
| OutputStream& operator<< (OutputStream& stream, const char character); | |||||
| OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const char* const text); | |||||
| OutputStream& operator<< (OutputStream& stream, const char* const text); | |||||
| #endif // __JUCE_OUTPUTSTREAM_JUCEHEADER__ | #endif // __JUCE_OUTPUTSTREAM_JUCEHEADER__ | ||||
| /*** End of inlined file: juce_OutputStream.h ***/ | /*** End of inlined file: juce_OutputStream.h ***/ | ||||
| @@ -2913,9 +2913,6 @@ public: | |||||
| bool isObject() const throw() { return type == objectType; } | bool isObject() const throw() { return type == objectType; } | ||||
| bool isMethod() const throw() { return type == methodType; } | bool isMethod() const throw() { return type == methodType; } | ||||
| bool operator== (const var& other) const throw(); | |||||
| bool operator!= (const var& other) const throw(); | |||||
| void writeToStream (OutputStream& output) const; | void writeToStream (OutputStream& output) const; | ||||
| static const var readFromStream (InputStream& input); | static const var readFromStream (InputStream& input); | ||||
| @@ -2956,6 +2953,8 @@ public: | |||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| bool equals (const var& other) const throw(); | |||||
| private: | private: | ||||
| enum Type | enum Type | ||||
| { | { | ||||
| @@ -2982,6 +2981,11 @@ private: | |||||
| ValueUnion value; | ValueUnion value; | ||||
| }; | }; | ||||
| bool operator== (const var& v1, const var& v2) throw(); | |||||
| bool operator!= (const var& v1, const var& v2) throw(); | |||||
| bool operator== (const var& v1, const String& v2) throw(); | |||||
| bool operator!= (const var& v1, const String& v2) throw(); | |||||
| #endif // __JUCE_VARIANT_JUCEHEADER__ | #endif // __JUCE_VARIANT_JUCEHEADER__ | ||||
| /*** End of inlined file: juce_Variant.h ***/ | /*** End of inlined file: juce_Variant.h ***/ | ||||
| @@ -8924,12 +8928,42 @@ private: | |||||
| #ifndef __JUCE_MOUSELISTENER_JUCEHEADER__ | #ifndef __JUCE_MOUSELISTENER_JUCEHEADER__ | ||||
| #define __JUCE_MOUSELISTENER_JUCEHEADER__ | #define __JUCE_MOUSELISTENER_JUCEHEADER__ | ||||
| class MouseEvent; | |||||
| class JUCE_API MouseListener | |||||
| { | |||||
| public: | |||||
| virtual ~MouseListener() {} | |||||
| virtual void mouseMove (const MouseEvent& e); | |||||
| virtual void mouseEnter (const MouseEvent& e); | |||||
| virtual void mouseExit (const MouseEvent& e); | |||||
| virtual void mouseDown (const MouseEvent& e); | |||||
| virtual void mouseDrag (const MouseEvent& e); | |||||
| virtual void mouseUp (const MouseEvent& e); | |||||
| virtual void mouseDoubleClick (const MouseEvent& e); | |||||
| virtual void mouseWheelMove (const MouseEvent& e, | |||||
| float wheelIncrementX, | |||||
| float wheelIncrementY); | |||||
| }; | |||||
| #endif // __JUCE_MOUSELISTENER_JUCEHEADER__ | |||||
| /*** End of inlined file: juce_MouseListener.h ***/ | |||||
| /*** Start of inlined file: juce_MouseEvent.h ***/ | /*** Start of inlined file: juce_MouseEvent.h ***/ | ||||
| #ifndef __JUCE_MOUSEEVENT_JUCEHEADER__ | #ifndef __JUCE_MOUSEEVENT_JUCEHEADER__ | ||||
| #define __JUCE_MOUSEEVENT_JUCEHEADER__ | #define __JUCE_MOUSEEVENT_JUCEHEADER__ | ||||
| class Component; | class Component; | ||||
| class MouseInputSource; | |||||
| /*** Start of inlined file: juce_ModifierKeys.h ***/ | /*** Start of inlined file: juce_ModifierKeys.h ***/ | ||||
| #ifndef __JUCE_MODIFIERKEYS_JUCEHEADER__ | #ifndef __JUCE_MODIFIERKEYS_JUCEHEADER__ | ||||
| @@ -8994,8 +9028,18 @@ public: | |||||
| allMouseButtonModifiers = leftButtonModifier | rightButtonModifier | middleButtonModifier, | allMouseButtonModifiers = leftButtonModifier | rightButtonModifier | middleButtonModifier, | ||||
| }; | }; | ||||
| const ModifierKeys withOnlyMouseButtons() const throw() { return ModifierKeys (flags & allMouseButtonModifiers); } | |||||
| const ModifierKeys withoutMouseButtons() const throw() { return ModifierKeys (flags & ~allMouseButtonModifiers); } | |||||
| bool operator== (const ModifierKeys& other) const throw() { return flags == other.flags; } | |||||
| bool operator!= (const ModifierKeys& other) const throw() { return flags != other.flags; } | |||||
| inline int getRawFlags() const throw() { return flags; } | inline int getRawFlags() const throw() { return flags; } | ||||
| inline const ModifierKeys withoutFlags (int rawFlagsToClear) const throw() { return ModifierKeys (flags & ~rawFlagsToClear); } | |||||
| inline const ModifierKeys withFlags (int rawFlagsToSet) const throw() { return ModifierKeys (flags | rawFlagsToSet); } | |||||
| inline bool testFlags (const int flagsToTest) const throw() { return (flags & flagsToTest) != 0; } | inline bool testFlags (const int flagsToTest) const throw() { return (flags & flagsToTest) != 0; } | ||||
| int getNumMouseButtonsDown() const throw(); | int getNumMouseButtonsDown() const throw(); | ||||
| @@ -9008,9 +9052,11 @@ private: | |||||
| int flags; | int flags; | ||||
| static int currentModifierFlags; | |||||
| static ModifierKeys currentModifiers; | |||||
| friend class ComponentPeer; | friend class ComponentPeer; | ||||
| friend class MouseInputSource; | |||||
| friend class MouseInputSourceInternal; | |||||
| static void updateCurrentModifiers() throw(); | static void updateCurrentModifiers() throw(); | ||||
| }; | }; | ||||
| @@ -9163,7 +9209,8 @@ class JUCE_API MouseEvent | |||||
| { | { | ||||
| public: | public: | ||||
| MouseEvent (const Point<int>& position, | |||||
| MouseEvent (MouseInputSource& source, | |||||
| const Point<int>& position, | |||||
| const ModifierKeys& modifiers, | const ModifierKeys& modifiers, | ||||
| Component* const originator, | Component* const originator, | ||||
| const Time& eventTime, | const Time& eventTime, | ||||
| @@ -9174,17 +9221,19 @@ public: | |||||
| ~MouseEvent() throw(); | ~MouseEvent() throw(); | ||||
| int x; | |||||
| const int x; | |||||
| int y; | |||||
| const int y; | |||||
| ModifierKeys mods; | |||||
| const ModifierKeys mods; | |||||
| Component* const eventComponent; | |||||
| Component* eventComponent; | |||||
| Component* const originalComponent; | |||||
| Component* originalComponent; | |||||
| const Time eventTime; | |||||
| Time eventTime; | |||||
| MouseInputSource& source; | |||||
| int getMouseDownX() const throw(); | int getMouseDownX() const throw(); | ||||
| @@ -9220,6 +9269,8 @@ public: | |||||
| const MouseEvent getEventRelativeTo (Component* const otherComponent) const throw(); | const MouseEvent getEventRelativeTo (Component* const otherComponent) const throw(); | ||||
| const MouseEvent withNewPosition (const Point<int>& newPosition) const throw(); | |||||
| static void setDoubleClickTimeout (const int timeOutMilliseconds) throw(); | static void setDoubleClickTimeout (const int timeOutMilliseconds) throw(); | ||||
| static int getDoubleClickTimeout() throw(); | static int getDoubleClickTimeout() throw(); | ||||
| @@ -9227,42 +9278,17 @@ public: | |||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| private: | private: | ||||
| Point<int> mouseDownPos; | |||||
| Time mouseDownTime; | |||||
| int numberOfClicks; | |||||
| bool wasMovedSinceMouseDown; | |||||
| const Point<int> mouseDownPos; | |||||
| const Time mouseDownTime; | |||||
| const int numberOfClicks; | |||||
| const bool wasMovedSinceMouseDown; | |||||
| MouseEvent& operator= (const MouseEvent&); | |||||
| }; | }; | ||||
| #endif // __JUCE_MOUSEEVENT_JUCEHEADER__ | #endif // __JUCE_MOUSEEVENT_JUCEHEADER__ | ||||
| /*** End of inlined file: juce_MouseEvent.h ***/ | /*** End of inlined file: juce_MouseEvent.h ***/ | ||||
| class JUCE_API MouseListener | |||||
| { | |||||
| public: | |||||
| virtual ~MouseListener() {} | |||||
| virtual void mouseMove (const MouseEvent& e); | |||||
| virtual void mouseEnter (const MouseEvent& e); | |||||
| virtual void mouseExit (const MouseEvent& e); | |||||
| virtual void mouseDown (const MouseEvent& e); | |||||
| virtual void mouseDrag (const MouseEvent& e); | |||||
| virtual void mouseUp (const MouseEvent& e); | |||||
| virtual void mouseDoubleClick (const MouseEvent& e); | |||||
| virtual void mouseWheelMove (const MouseEvent& e, | |||||
| float wheelIncrementX, | |||||
| float wheelIncrementY); | |||||
| }; | |||||
| #endif // __JUCE_MOUSELISTENER_JUCEHEADER__ | |||||
| /*** End of inlined file: juce_MouseListener.h ***/ | |||||
| /*** Start of inlined file: juce_ComponentListener.h ***/ | /*** Start of inlined file: juce_ComponentListener.h ***/ | ||||
| #ifndef __JUCE_COMPONENTLISTENER_JUCEHEADER__ | #ifndef __JUCE_COMPONENTLISTENER_JUCEHEADER__ | ||||
| @@ -11966,7 +11992,7 @@ public: | |||||
| class ComponentBoundsConstrainer; | class ComponentBoundsConstrainer; | ||||
| class ComponentDeletionWatcher; | class ComponentDeletionWatcher; | ||||
| class JUCE_API ComponentPeer : public MessageListener | |||||
| class JUCE_API ComponentPeer | |||||
| { | { | ||||
| public: | public: | ||||
| @@ -12047,7 +12073,7 @@ public: | |||||
| ComponentBoundsConstrainer* getConstrainer() const throw() { return constrainer; } | ComponentBoundsConstrainer* getConstrainer() const throw() { return constrainer; } | ||||
| virtual bool contains (int x, int y, bool trueIfInAChildWindow) const = 0; | |||||
| virtual bool contains (const Point<int>& position, bool trueIfInAChildWindow) const = 0; | |||||
| virtual const BorderSize getFrameSize() const = 0; | virtual const BorderSize getFrameSize() const = 0; | ||||
| @@ -12089,15 +12115,8 @@ public: | |||||
| virtual void performAnyPendingRepaintsNow() = 0; | virtual void performAnyPendingRepaintsNow() = 0; | ||||
| void handleMouseEnter (const Point<int>& position, const int64 time); | |||||
| void handleMouseMove (const Point<int>& position, const int64 time); | |||||
| void handleMouseDown (const Point<int>& position, const int64 time); | |||||
| void handleMouseDrag (const Point<int>& position, const int64 time); | |||||
| void handleMouseUp (const int oldModifiers, const Point<int>& position, const int64 time); | |||||
| void handleMouseExit (const Point<int>& position, const int64 time); | |||||
| void handleMouseWheel (const int amountX, const int amountY, const int64 time); | |||||
| void sendFakeMouseMove() throw(); | |||||
| void handleMouseEvent (const Point<int>& positionWithinPeer, const ModifierKeys& newMods, const int64 time); | |||||
| void handleMouseWheel (const Point<int>& positionWithinPeer, const int64 time, float x, float y); | |||||
| void handleUserClosingWindow(); | void handleUserClosingWindow(); | ||||
| @@ -12133,8 +12152,6 @@ protected: | |||||
| static void updateCurrentModifiers() throw(); | static void updateCurrentModifiers() throw(); | ||||
| void handleMessage (const Message& message); | |||||
| private: | private: | ||||
| Component* lastFocusedComponent; | Component* lastFocusedComponent; | ||||
| @@ -12155,6 +12172,8 @@ private: | |||||
| /*** End of inlined file: juce_ComponentPeer.h ***/ | /*** End of inlined file: juce_ComponentPeer.h ***/ | ||||
| class LookAndFeel; | class LookAndFeel; | ||||
| class MouseInputSource; | |||||
| class MouseInputSourceInternal; | |||||
| class JUCE_API Component : public MouseListener, | class JUCE_API Component : public MouseListener, | ||||
| protected MessageListener | protected MessageListener | ||||
| @@ -12545,6 +12564,8 @@ private: | |||||
| friend class ComponentPeer; | friend class ComponentPeer; | ||||
| friend class InternalDragRepeater; | friend class InternalDragRepeater; | ||||
| friend class MouseInputSource; | |||||
| friend class MouseInputSourceInternal; | |||||
| static Component* currentlyFocusedComponent; | static Component* currentlyFocusedComponent; | ||||
| static Component* componentUnderMouse; | static Component* componentUnderMouse; | ||||
| @@ -12595,13 +12616,13 @@ private: | |||||
| ComponentFlags flags; | ComponentFlags flags; | ||||
| }; | }; | ||||
| void internalMouseEnter (int x, int y, const int64 time); | |||||
| void internalMouseExit (int x, int y, const int64 time); | |||||
| void internalMouseDown (int x, int y, const int64 time); | |||||
| void internalMouseUp (const int oldModifiers, int x, int y, const int64 time); | |||||
| void internalMouseDrag (int x, int y, const int64 time); | |||||
| void internalMouseMove (int x, int y, const int64 time); | |||||
| void internalMouseWheel (const int intAmountX, const int intAmountY, const int64 time); | |||||
| void internalMouseEnter (MouseInputSource& source, const Point<int>& relativePos, const Time& time); | |||||
| void internalMouseExit (MouseInputSource& source, const Point<int>& relativePos, const Time& time); | |||||
| void internalMouseDown (MouseInputSource& source, const Point<int>& relativePos, const Time& time); | |||||
| void internalMouseUp (MouseInputSource& source, const Point<int>& relativePos, const Time& time, const ModifierKeys& oldModifiers); | |||||
| void internalMouseDrag (MouseInputSource& source, const Point<int>& relativePos, const Time& time); | |||||
| void internalMouseMove (MouseInputSource& source, const Point<int>& relativePos, const Time& time); | |||||
| void internalMouseWheel (MouseInputSource& source, const Point<int>& relativePos, const Time& time, const float amountX, const float amountY); | |||||
| void internalBroughtToFront(); | void internalBroughtToFront(); | ||||
| void internalFocusGain (const FocusChangeType cause); | void internalFocusGain (const FocusChangeType cause); | ||||
| void internalFocusLoss (const FocusChangeType cause); | void internalFocusLoss (const FocusChangeType cause); | ||||
| @@ -12998,6 +13019,10 @@ private: | |||||
| #endif // __JUCE_TIMER_JUCEHEADER__ | #endif // __JUCE_TIMER_JUCEHEADER__ | ||||
| /*** End of inlined file: juce_Timer.h ***/ | /*** End of inlined file: juce_Timer.h ***/ | ||||
| class MouseInputSource; | |||||
| class MouseInputSourceInternal; | |||||
| class MouseListener; | |||||
| class JUCE_API FocusChangeListener | class JUCE_API FocusChangeListener | ||||
| { | { | ||||
| public: | public: | ||||
| @@ -13057,12 +13082,18 @@ public: | |||||
| static bool canUseSemiTransparentWindows() throw(); | static bool canUseSemiTransparentWindows() throw(); | ||||
| int getNumMouseInputSources() const throw() { return mouseSources.size(); } | |||||
| MouseInputSource* getMouseSource (int index) const throw() { return mouseSources [index]; } | |||||
| MouseInputSource& getMainMouseSource() const throw() { return *mouseSources.getUnchecked(0); } | |||||
| private: | private: | ||||
| static Desktop* instance; | static Desktop* instance; | ||||
| friend class Component; | friend class Component; | ||||
| friend class ComponentPeer; | friend class ComponentPeer; | ||||
| friend class MouseInputSource; | |||||
| friend class MouseInputSourceInternal; | |||||
| SortedSet <void*> mouseListeners, focusListeners; | SortedSet <void*> mouseListeners, focusListeners; | ||||
| Array <Component*> desktopComponents; | Array <Component*> desktopComponents; | ||||
| @@ -13073,24 +13104,12 @@ private: | |||||
| Array <Rectangle<int> > monitorCoordsClipped, monitorCoordsUnclipped; | Array <Rectangle<int> > monitorCoordsClipped, monitorCoordsUnclipped; | ||||
| OwnedArray <MouseInputSource> mouseSources; | |||||
| Point<int> lastFakeMouseMove; | Point<int> lastFakeMouseMove; | ||||
| int mouseClickCounter; | int mouseClickCounter; | ||||
| bool mouseMovedSignificantlySincePressed; | |||||
| struct RecentMouseDown | |||||
| { | |||||
| Point<int> position; | |||||
| int64 time; | |||||
| Component* component; | |||||
| }; | |||||
| RecentMouseDown mouseDowns[4]; | |||||
| void incrementMouseClickCounter() throw(); | void incrementMouseClickCounter() throw(); | ||||
| void registerMouseDown (const Point<int>& position, int64 time, Component* component) throw(); | |||||
| void registerMouseDrag (const Point<int>& position) throw(); | |||||
| const Time getLastMouseDownTime() const throw(); | |||||
| int getNumberOfMultipleClicks() const throw(); | |||||
| Component* kioskModeComponent; | Component* kioskModeComponent; | ||||
| Rectangle<int> kioskComponentOriginalBounds; | Rectangle<int> kioskComponentOriginalBounds; | ||||
| @@ -25899,6 +25918,7 @@ public: | |||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| private: | private: | ||||
| class ActiveXControlData; | |||||
| friend class ActiveXControlData; | friend class ActiveXControlData; | ||||
| void* control; | void* control; | ||||
| bool mouseEventsAllowed; | bool mouseEventsAllowed; | ||||
| @@ -26176,6 +26196,69 @@ 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(); | |||||
| 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: | ||||
| @@ -26204,6 +26287,7 @@ private: | |||||
| ComponentPeer* peer; | ComponentPeer* peer; | ||||
| bool deleteContent; | bool deleteContent; | ||||
| Graphics::ResamplingQuality quality; | Graphics::ResamplingQuality quality; | ||||
| MouseInputSource mouseSource; | |||||
| void paint (Graphics& g); | void paint (Graphics& g); | ||||
| void mouseDown (const MouseEvent& e); | void mouseDown (const MouseEvent& e); | ||||
| @@ -26214,6 +26298,7 @@ private: | |||||
| void mouseExit (const MouseEvent& e); | void mouseExit (const MouseEvent& e); | ||||
| void mouseWheelMove (const MouseEvent& e, float, float); | void mouseWheelMove (const MouseEvent& e, float, float); | ||||
| void passOnMouseEventToPeer (const MouseEvent& e); | |||||
| int scaleInt (const int n) const; | int scaleInt (const int n) const; | ||||
| MagnifierComponent (const MagnifierComponent&); | MagnifierComponent (const MagnifierComponent&); | ||||
| @@ -169,7 +169,7 @@ public: | |||||
| /** Returns true if this var has the same value as the one supplied. */ | /** Returns true if this var has the same value as the one supplied. */ | ||||
| bool equals (const var& other) const throw(); | bool equals (const var& other) const throw(); | ||||
| private: | private: | ||||
| enum Type | enum Type | ||||
| { | { | ||||
| @@ -33,7 +33,7 @@ | |||||
| */ | */ | ||||
| #define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
| #define JUCE_MINOR_VERSION 51 | #define JUCE_MINOR_VERSION 51 | ||||
| #define JUCE_BUILDNUMBER 2 | |||||
| #define JUCE_BUILDNUMBER 3 | |||||
| /** Current Juce version number. | /** Current Juce version number. | ||||
| @@ -1148,35 +1148,32 @@ void Slider::restoreMouseIfHidden() | |||||
| : ((sliderBeingDragged == 1) ? getMinValue() | : ((sliderBeingDragged == 1) ? getMinValue() | ||||
| : (double) currentValue.getValue()); | : (double) currentValue.getValue()); | ||||
| Point<int> mousePos; | |||||
| if (style == RotaryHorizontalDrag || style == RotaryVerticalDrag) | if (style == RotaryHorizontalDrag || style == RotaryVerticalDrag) | ||||
| { | { | ||||
| Point<int> mousePos (Desktop::getMousePosition()); | |||||
| const Point<int> lastMouseDown (Desktop::getLastMouseDownPosition()); | |||||
| mousePos = Desktop::getLastMouseDownPosition(); | |||||
| if (style == RotaryHorizontalDrag) | if (style == RotaryHorizontalDrag) | ||||
| { | { | ||||
| const double posDiff = valueToProportionOfLength (pos) - valueToProportionOfLength (valueOnMouseDown); | const double posDiff = valueToProportionOfLength (pos) - valueToProportionOfLength (valueOnMouseDown); | ||||
| mousePos = Point<int> (roundToInt (pixelsForFullDragExtent * posDiff + lastMouseDown.getX()), | |||||
| lastMouseDown.getY()); | |||||
| mousePos += Point<int> (roundToInt (pixelsForFullDragExtent * posDiff), 0); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| const double posDiff = valueToProportionOfLength (valueOnMouseDown) - valueToProportionOfLength (pos); | const double posDiff = valueToProportionOfLength (valueOnMouseDown) - valueToProportionOfLength (pos); | ||||
| mousePos = Point<int> (lastMouseDown.getX(), | |||||
| roundToInt (pixelsForFullDragExtent * posDiff + lastMouseDown.getY())); | |||||
| mousePos += Point<int> (0, roundToInt (pixelsForFullDragExtent * posDiff)); | |||||
| } | } | ||||
| Desktop::setMousePosition (mousePos); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| const int pixelPos = (int) getLinearSliderPos (pos); | const int pixelPos = (int) getLinearSliderPos (pos); | ||||
| const Point<int> pos (isHorizontal() ? pixelPos : (getWidth() / 2), | |||||
| isVertical() ? pixelPos : (getHeight() / 2)); | |||||
| Desktop::setMousePosition (relativePositionToGlobal (pos)); | |||||
| mousePos = relativePositionToGlobal (Point<int> (isHorizontal() ? pixelPos : (getWidth() / 2), | |||||
| isVertical() ? pixelPos : (getHeight() / 2))); | |||||
| } | } | ||||
| Desktop::setMousePosition (mousePos); | |||||
| } | } | ||||
| } | } | ||||
| @@ -83,12 +83,8 @@ public: | |||||
| else | else | ||||
| selectBasedOnModifiers (item, e.mods); | selectBasedOnModifiers (item, e.mods); | ||||
| MouseEvent e2 (e); | |||||
| e2.x -= pos.getX(); | |||||
| e2.y -= pos.getY(); | |||||
| if (e2.x >= 0) | |||||
| item->itemClicked (e2); | |||||
| if (e.x >= pos.getX()) | |||||
| item->itemClicked (e.withNewPosition (e.getPosition() - pos.getPosition())); | |||||
| } | } | ||||
| } | } | ||||
| @@ -114,12 +110,7 @@ public: | |||||
| TreeViewItem* const item = findItemAt (e.y, pos); | TreeViewItem* const item = findItemAt (e.y, pos); | ||||
| if (item != 0 && (e.x >= pos.getX() || ! owner->openCloseButtonsVisible)) | if (item != 0 && (e.x >= pos.getX() || ! owner->openCloseButtonsVisible)) | ||||
| { | |||||
| MouseEvent e2 (e); | |||||
| e2.x -= pos.getX(); | |||||
| e2.y -= pos.getY(); | |||||
| item->itemDoubleClicked (e2); | |||||
| } | |||||
| item->itemDoubleClicked (e.withNewPosition (e.getPosition() - pos.getPosition())); | |||||
| } | } | ||||
| } | } | ||||
| @@ -39,8 +39,9 @@ BEGIN_JUCE_NAMESPACE | |||||
| #include "../../events/juce_MessageManager.h" | #include "../../events/juce_MessageManager.h" | ||||
| #include "../../events/juce_Timer.h" | #include "../../events/juce_Timer.h" | ||||
| #include "../../core/juce_Time.h" | #include "../../core/juce_Time.h" | ||||
| #include "../../core/juce_Singleton.h" | |||||
| #include "../../core/juce_PlatformUtilities.h" | #include "../../core/juce_PlatformUtilities.h" | ||||
| #include "mouse/juce_MouseInputSource.h" | |||||
| //============================================================================== | //============================================================================== | ||||
| Component* Component::componentUnderMouse = 0; | Component* Component::componentUnderMouse = 0; | ||||
| @@ -1084,7 +1085,7 @@ bool Component::contains (const int x, const int y) | |||||
| const ComponentPeer* const peer = getPeer(); | const ComponentPeer* const peer = getPeer(); | ||||
| if (peer != 0) | if (peer != 0) | ||||
| return peer->contains (x, y, true); | |||||
| return peer->contains (Point<int> (x, y), true); | |||||
| } | } | ||||
| } | } | ||||
| @@ -2226,7 +2227,7 @@ void Component::removeMouseListener (MouseListener* const listenerToRemove) thro | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| void Component::internalMouseEnter (int x, int y, int64 time) | |||||
| void Component::internalMouseEnter (MouseInputSource& source, const Point<int>& relativePos, const Time& time) | |||||
| { | { | ||||
| if (isCurrentlyBlockedByAnotherModalComponent()) | if (isCurrentlyBlockedByAnotherModalComponent()) | ||||
| { | { | ||||
| @@ -2256,13 +2257,9 @@ void Component::internalMouseEnter (int x, int y, int64 time) | |||||
| if (flags.repaintOnMouseActivityFlag) | if (flags.repaintOnMouseActivityFlag) | ||||
| repaint(); | repaint(); | ||||
| const MouseEvent me (Point<int> (x, y), | |||||
| ModifierKeys::getCurrentModifiers(), | |||||
| this, | |||||
| Time (time), | |||||
| Point<int> (x, y), | |||||
| Time (time), | |||||
| 0, false); | |||||
| const MouseEvent me (source, relativePos, source.getCurrentModifiers(), | |||||
| this, time, relativePos, | |||||
| time, 0, false); | |||||
| mouseEnter (me); | mouseEnter (me); | ||||
| @@ -2318,13 +2315,13 @@ void Component::internalMouseEnter (int x, int y, int64 time) | |||||
| internalUpdateMouseCursor (true); | internalUpdateMouseCursor (true); | ||||
| } | } | ||||
| void Component::internalMouseExit (int x, int y, int64 time) | |||||
| void Component::internalMouseExit (MouseInputSource& source, const Point<int>& relativePos, const Time& time) | |||||
| { | { | ||||
| const ComponentDeletionWatcher deletionChecker (this); | const ComponentDeletionWatcher deletionChecker (this); | ||||
| if (flags.draggingFlag) | if (flags.draggingFlag) | ||||
| { | { | ||||
| internalMouseUp (ModifierKeys::getCurrentModifiers().getRawFlags(), x, y, time); | |||||
| internalMouseUp (source, relativePos, time, source.getCurrentModifiers().getRawFlags()); | |||||
| if (deletionChecker.hasBeenDeleted()) | if (deletionChecker.hasBeenDeleted()) | ||||
| return; | return; | ||||
| @@ -2341,13 +2338,9 @@ void Component::internalMouseExit (int x, int y, int64 time) | |||||
| if (flags.repaintOnMouseActivityFlag) | if (flags.repaintOnMouseActivityFlag) | ||||
| repaint(); | repaint(); | ||||
| const MouseEvent me (Point<int> (x, y), | |||||
| ModifierKeys::getCurrentModifiers(), | |||||
| this, | |||||
| Time (time), | |||||
| Point<int> (x, y), | |||||
| Time (time), | |||||
| 0, false); | |||||
| const MouseEvent me (source, relativePos, source.getCurrentModifiers(), | |||||
| this, time, relativePos, | |||||
| time, 0, false); | |||||
| mouseExit (me); | mouseExit (me); | ||||
| if (deletionChecker.hasBeenDeleted()) | if (deletionChecker.hasBeenDeleted()) | ||||
| @@ -2403,23 +2396,33 @@ void Component::internalMouseExit (int x, int y, int64 time) | |||||
| class InternalDragRepeater : public Timer | class InternalDragRepeater : public Timer | ||||
| { | { | ||||
| public: | public: | ||||
| InternalDragRepeater() {} | |||||
| ~InternalDragRepeater() {} | |||||
| InternalDragRepeater() | |||||
| {} | |||||
| ~InternalDragRepeater() | |||||
| { | |||||
| clearSingletonInstance(); | |||||
| } | |||||
| juce_DeclareSingleton_SingleThreaded_Minimal (InternalDragRepeater) | |||||
| void timerCallback() | void timerCallback() | ||||
| { | { | ||||
| Component* const c = Component::getComponentUnderMouse(); | |||||
| Desktop& desktop = Desktop::getInstance(); | |||||
| int numMiceDown = 0; | |||||
| if (c != 0 && c->isMouseButtonDown()) | |||||
| for (int i = desktop.getNumMouseInputSources(); --i >= 0;) | |||||
| { | { | ||||
| const Point<int> mousePos (c->getMouseXYRelative()); | |||||
| // the offsets have been added on, so must be taken off before calling the | |||||
| // drag.. otherwise they'll be added twice | |||||
| c->internalMouseDrag (mousePos.getX() - unboundedMouseOffset.getX(), | |||||
| mousePos.getY() - unboundedMouseOffset.getY(), | |||||
| Time::currentTimeMillis()); | |||||
| MouseInputSource* const source = desktop.getMouseSource(i); | |||||
| if (source->isDragging()) | |||||
| { | |||||
| source->triggerFakeMove(); | |||||
| ++numMiceDown; | |||||
| } | |||||
| } | } | ||||
| if (numMiceDown == 0) | |||||
| deleteInstance(); | |||||
| } | } | ||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| @@ -2429,31 +2432,27 @@ private: | |||||
| InternalDragRepeater& operator= (const InternalDragRepeater&); | InternalDragRepeater& operator= (const InternalDragRepeater&); | ||||
| }; | }; | ||||
| static InternalDragRepeater* dragRepeater = 0; | |||||
| juce_ImplementSingleton_SingleThreaded (InternalDragRepeater) | |||||
| void Component::beginDragAutoRepeat (const int interval) | void Component::beginDragAutoRepeat (const int interval) | ||||
| { | { | ||||
| if (interval > 0) | if (interval > 0) | ||||
| { | { | ||||
| if (dragRepeater == 0) | |||||
| dragRepeater = new InternalDragRepeater(); | |||||
| if (dragRepeater->getTimerInterval() != interval) | |||||
| dragRepeater->startTimer (interval); | |||||
| if (InternalDragRepeater::getInstance()->getTimerInterval() != interval) | |||||
| InternalDragRepeater::getInstance()->startTimer (interval); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| deleteAndZero (dragRepeater); | |||||
| InternalDragRepeater::deleteInstance(); | |||||
| } | } | ||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| void Component::internalMouseDown (const int x, const int y, const int64 time) | |||||
| void Component::internalMouseDown (MouseInputSource& source, const Point<int>& relativePos, const Time& time) | |||||
| { | { | ||||
| Desktop& desktop = Desktop::getInstance(); | Desktop& desktop = Desktop::getInstance(); | ||||
| desktop.registerMouseDown (relativePositionToGlobal (Point<int> (x, y)), time, this); | |||||
| const ComponentDeletionWatcher deletionChecker (this); | const ComponentDeletionWatcher deletionChecker (this); | ||||
| if (isCurrentlyBlockedByAnotherModalComponent()) | if (isCurrentlyBlockedByAnotherModalComponent()) | ||||
| @@ -2468,14 +2467,9 @@ void Component::internalMouseDown (const int x, const int y, const int64 time) | |||||
| if (isCurrentlyBlockedByAnotherModalComponent()) | if (isCurrentlyBlockedByAnotherModalComponent()) | ||||
| { | { | ||||
| // allow blocked mouse-events to go to global listeners.. | // allow blocked mouse-events to go to global listeners.. | ||||
| const MouseEvent me (Point<int> (x, y), | |||||
| ModifierKeys::getCurrentModifiers(), | |||||
| this, | |||||
| Time (time), | |||||
| Point<int> (x, y), | |||||
| desktop.getLastMouseDownTime(), | |||||
| desktop.getNumberOfMultipleClicks(), | |||||
| false); | |||||
| const MouseEvent me (source, relativePos, source.getCurrentModifiers(), | |||||
| this, time, relativePos, time, | |||||
| source.getNumberOfMultipleClicks(), false); | |||||
| desktop.resetTimer(); | desktop.resetTimer(); | ||||
| @@ -2521,14 +2515,9 @@ void Component::internalMouseDown (const int x, const int y, const int64 time) | |||||
| if (flags.repaintOnMouseActivityFlag) | if (flags.repaintOnMouseActivityFlag) | ||||
| repaint(); | repaint(); | ||||
| const MouseEvent me (Point<int> (x, y), | |||||
| ModifierKeys::getCurrentModifiers(), | |||||
| this, | |||||
| desktop.getLastMouseDownTime(), | |||||
| Point<int> (x, y), | |||||
| desktop.getLastMouseDownTime(), | |||||
| desktop.getNumberOfMultipleClicks(), | |||||
| false); | |||||
| const MouseEvent me (source, relativePos, source.getCurrentModifiers(), | |||||
| this, time, relativePos, time, | |||||
| source.getNumberOfMultipleClicks(), false); | |||||
| mouseDown (me); | mouseDown (me); | ||||
| if (deletionChecker.hasBeenDeleted()) | if (deletionChecker.hasBeenDeleted()) | ||||
| @@ -2581,37 +2570,25 @@ void Component::internalMouseDown (const int x, const int y, const int64 time) | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| void Component::internalMouseUp (const int oldModifiers, int x, int y, const int64 time) | |||||
| void Component::internalMouseUp (MouseInputSource& source, const Point<int>& relativePos, const Time& time, const ModifierKeys& oldModifiers) | |||||
| { | { | ||||
| if (isValidComponent() && flags.draggingFlag) | if (isValidComponent() && flags.draggingFlag) | ||||
| { | { | ||||
| Desktop& desktop = Desktop::getInstance(); | Desktop& desktop = Desktop::getInstance(); | ||||
| flags.draggingFlag = false; | flags.draggingFlag = false; | ||||
| deleteAndZero (dragRepeater); | |||||
| x += unboundedMouseOffset.getX(); | |||||
| y += unboundedMouseOffset.getY(); | |||||
| desktop.registerMouseDrag (relativePositionToGlobal (Point<int> (x, y))); | |||||
| const ComponentDeletionWatcher deletionChecker (this); | const ComponentDeletionWatcher deletionChecker (this); | ||||
| if (flags.repaintOnMouseActivityFlag) | if (flags.repaintOnMouseActivityFlag) | ||||
| repaint(); | repaint(); | ||||
| const Point<int> mouseDownPos (globalPositionToRelative (Desktop::getLastMouseDownPosition())); | |||||
| const Time lastMouseDownTime (desktop.getLastMouseDownTime()); | |||||
| const MouseEvent me (Point<int> (x, y), | |||||
| oldModifiers, | |||||
| this, | |||||
| Time (time), | |||||
| mouseDownPos, | |||||
| lastMouseDownTime, | |||||
| desktop.getNumberOfMultipleClicks(), | |||||
| desktop.mouseMovedSignificantlySincePressed | |||||
| || time > lastMouseDownTime.toMilliseconds() + 300); | |||||
| const MouseEvent me (source, relativePos + unboundedMouseOffset, | |||||
| oldModifiers, this, time, | |||||
| globalPositionToRelative (source.getLastMouseDownPosition()), | |||||
| source.getLastMouseDownTime(), | |||||
| source.getNumberOfMultipleClicks(), | |||||
| source.hasMouseMovedSignificantlySincePressed()); | |||||
| mouseUp (me); | mouseUp (me); | ||||
| @@ -2719,33 +2696,22 @@ void Component::internalMouseUp (const int oldModifiers, int x, int y, const int | |||||
| enableUnboundedMouseMovement (false); | enableUnboundedMouseMovement (false); | ||||
| } | } | ||||
| void Component::internalMouseDrag (int x, int y, const int64 time) | |||||
| void Component::internalMouseDrag (MouseInputSource& source, const Point<int>& relativePos, const Time& time) | |||||
| { | { | ||||
| if (isValidComponent() && flags.draggingFlag) | if (isValidComponent() && flags.draggingFlag) | ||||
| { | { | ||||
| Desktop& desktop = Desktop::getInstance(); | Desktop& desktop = Desktop::getInstance(); | ||||
| flags.mouseOverFlag = reallyContains (x, y, false); | |||||
| x += unboundedMouseOffset.getX(); | |||||
| y += unboundedMouseOffset.getY(); | |||||
| desktop.registerMouseDrag (relativePositionToGlobal (Point<int> (x, y))); | |||||
| flags.mouseOverFlag = reallyContains (relativePos.getX(), relativePos.getY(), false); | |||||
| const ComponentDeletionWatcher deletionChecker (this); | const ComponentDeletionWatcher deletionChecker (this); | ||||
| const Point<int> mouseDownPos (globalPositionToRelative (Desktop::getLastMouseDownPosition())); | |||||
| const Time lastMouseDownTime (desktop.getLastMouseDownTime()); | |||||
| const MouseEvent me (Point<int> (x, y), | |||||
| ModifierKeys::getCurrentModifiers(), | |||||
| this, | |||||
| Time (time), | |||||
| mouseDownPos, | |||||
| lastMouseDownTime, | |||||
| desktop.getNumberOfMultipleClicks(), | |||||
| desktop.mouseMovedSignificantlySincePressed | |||||
| || time > lastMouseDownTime.toMilliseconds() + 300); | |||||
| const MouseEvent me (source, relativePos + unboundedMouseOffset, | |||||
| source.getCurrentModifiers(), this, time, | |||||
| globalPositionToRelative (source.getLastMouseDownPosition()), | |||||
| source.getLastMouseDownTime(), | |||||
| source.getNumberOfMultipleClicks(), | |||||
| source.hasMouseMovedSignificantlySincePressed()); | |||||
| mouseDrag (me); | mouseDrag (me); | ||||
| @@ -2800,8 +2766,8 @@ void Component::internalMouseDrag (int x, int y, const int64 time) | |||||
| { | { | ||||
| if (isUnboundedMouseModeOn) | if (isUnboundedMouseModeOn) | ||||
| { | { | ||||
| Rectangle<int> screenArea (getParentMonitorArea().expanded (-2, -2)); | |||||
| Point<int> mousePos (Desktop::getMousePosition()); | |||||
| const Rectangle<int> screenArea (getParentMonitorArea().expanded (-2, -2)); | |||||
| Point<int> mousePos (source.getScreenPosition()); | |||||
| if (! screenArea.contains (mousePos)) | if (! screenArea.contains (mousePos)) | ||||
| { | { | ||||
| @@ -2833,7 +2799,7 @@ void Component::internalMouseDrag (int x, int y, const int64 time) | |||||
| } | } | ||||
| } | } | ||||
| void Component::internalMouseMove (const int x, const int y, const int64 time) | |||||
| void Component::internalMouseMove (MouseInputSource& source, const Point<int>& relativePos, const Time& time) | |||||
| { | { | ||||
| const ComponentDeletionWatcher deletionChecker (this); | const ComponentDeletionWatcher deletionChecker (this); | ||||
| @@ -2841,13 +2807,9 @@ void Component::internalMouseMove (const int x, const int y, const int64 time) | |||||
| { | { | ||||
| Desktop& desktop = Desktop::getInstance(); | Desktop& desktop = Desktop::getInstance(); | ||||
| const MouseEvent me (Point<int> (x, y), | |||||
| ModifierKeys::getCurrentModifiers(), | |||||
| this, | |||||
| Time (time), | |||||
| Point<int> (x, y), | |||||
| Time (time), | |||||
| 0, false); | |||||
| const MouseEvent me (source, relativePos, source.getCurrentModifiers(), | |||||
| this, time, relativePos, | |||||
| time, 0, false); | |||||
| if (isCurrentlyBlockedByAnotherModalComponent()) | if (isCurrentlyBlockedByAnotherModalComponent()) | ||||
| { | { | ||||
| @@ -2913,23 +2875,17 @@ void Component::internalMouseMove (const int x, const int y, const int64 time) | |||||
| } | } | ||||
| } | } | ||||
| void Component::internalMouseWheel (const int intAmountX, const int intAmountY, const int64 time) | |||||
| void Component::internalMouseWheel (MouseInputSource& source, const Point<int>& relativePos, | |||||
| const Time& time, const float amountX, const float amountY) | |||||
| { | { | ||||
| Desktop& desktop = Desktop::getInstance(); | Desktop& desktop = Desktop::getInstance(); | ||||
| const ComponentDeletionWatcher deletionChecker (this); | const ComponentDeletionWatcher deletionChecker (this); | ||||
| const float wheelIncrementX = intAmountX * (1.0f / 256.0f); | |||||
| const float wheelIncrementY = intAmountY * (1.0f / 256.0f); | |||||
| const float wheelIncrementX = amountX * (1.0f / 256.0f); | |||||
| const float wheelIncrementY = amountY * (1.0f / 256.0f); | |||||
| const Point<int> mousePos (getMouseXYRelative()); | |||||
| const MouseEvent me (mousePos, | |||||
| ModifierKeys::getCurrentModifiers(), | |||||
| this, | |||||
| Time (time), | |||||
| mousePos, | |||||
| Time (time), | |||||
| 0, false); | |||||
| const MouseEvent me (source, relativePos, source.getCurrentModifiers(), | |||||
| this, time, relativePos, time, 0, false); | |||||
| if (isCurrentlyBlockedByAnotherModalComponent()) | if (isCurrentlyBlockedByAnotherModalComponent()) | ||||
| { | { | ||||
| @@ -2992,17 +2948,12 @@ void Component::internalMouseWheel (const int intAmountX, const int intAmountY, | |||||
| p = p->parentComponent_; | p = p->parentComponent_; | ||||
| } | } | ||||
| sendFakeMouseMove(); | |||||
| } | } | ||||
| } | } | ||||
| void Component::sendFakeMouseMove() const | void Component::sendFakeMouseMove() const | ||||
| { | { | ||||
| ComponentPeer* const peer = getPeer(); | |||||
| if (peer != 0) | |||||
| peer->sendFakeMouseMove(); | |||||
| Desktop::getInstance().getMainMouseSource().triggerFakeMove(); | |||||
| } | } | ||||
| void Component::broughtToFront() | void Component::broughtToFront() | ||||
| @@ -28,6 +28,7 @@ | |||||
| #include "mouse/juce_MouseCursor.h" | #include "mouse/juce_MouseCursor.h" | ||||
| #include "mouse/juce_MouseListener.h" | #include "mouse/juce_MouseListener.h" | ||||
| #include "mouse/juce_MouseEvent.h" | |||||
| #include "juce_ComponentListener.h" | #include "juce_ComponentListener.h" | ||||
| #include "keyboard/juce_KeyListener.h" | #include "keyboard/juce_KeyListener.h" | ||||
| #include "keyboard/juce_KeyboardFocusTraverser.h" | #include "keyboard/juce_KeyboardFocusTraverser.h" | ||||
| @@ -40,6 +41,8 @@ | |||||
| #include "../../containers/juce_VoidArray.h" | #include "../../containers/juce_VoidArray.h" | ||||
| #include "../../containers/juce_NamedValueSet.h" | #include "../../containers/juce_NamedValueSet.h" | ||||
| class LookAndFeel; | class LookAndFeel; | ||||
| class MouseInputSource; | |||||
| class MouseInputSourceInternal; | |||||
| //============================================================================== | //============================================================================== | ||||
| @@ -1921,6 +1924,8 @@ private: | |||||
| //============================================================================== | //============================================================================== | ||||
| friend class ComponentPeer; | friend class ComponentPeer; | ||||
| friend class InternalDragRepeater; | friend class InternalDragRepeater; | ||||
| friend class MouseInputSource; | |||||
| friend class MouseInputSourceInternal; | |||||
| static Component* currentlyFocusedComponent; | static Component* currentlyFocusedComponent; | ||||
| static Component* componentUnderMouse; | static Component* componentUnderMouse; | ||||
| @@ -1973,13 +1978,13 @@ private: | |||||
| }; | }; | ||||
| //============================================================================== | //============================================================================== | ||||
| void internalMouseEnter (int x, int y, const int64 time); | |||||
| void internalMouseExit (int x, int y, const int64 time); | |||||
| void internalMouseDown (int x, int y, const int64 time); | |||||
| void internalMouseUp (const int oldModifiers, int x, int y, const int64 time); | |||||
| void internalMouseDrag (int x, int y, const int64 time); | |||||
| void internalMouseMove (int x, int y, const int64 time); | |||||
| void internalMouseWheel (const int intAmountX, const int intAmountY, const int64 time); | |||||
| void internalMouseEnter (MouseInputSource& source, const Point<int>& relativePos, const Time& time); | |||||
| void internalMouseExit (MouseInputSource& source, const Point<int>& relativePos, const Time& time); | |||||
| void internalMouseDown (MouseInputSource& source, const Point<int>& relativePos, const Time& time); | |||||
| void internalMouseUp (MouseInputSource& source, const Point<int>& relativePos, const Time& time, const ModifierKeys& oldModifiers); | |||||
| void internalMouseDrag (MouseInputSource& source, const Point<int>& relativePos, const Time& time); | |||||
| void internalMouseMove (MouseInputSource& source, const Point<int>& relativePos, const Time& time); | |||||
| void internalMouseWheel (MouseInputSource& source, const Point<int>& relativePos, const Time& time, const float amountX, const float amountY); | |||||
| void internalBroughtToFront(); | void internalBroughtToFront(); | ||||
| void internalFocusGain (const FocusChangeType cause); | void internalFocusGain (const FocusChangeType cause); | ||||
| void internalFocusLoss (const FocusChangeType cause); | void internalFocusLoss (const FocusChangeType cause); | ||||
| @@ -30,15 +30,20 @@ BEGIN_JUCE_NAMESPACE | |||||
| #include "juce_Desktop.h" | #include "juce_Desktop.h" | ||||
| #include "juce_ComponentDeletionWatcher.h" | #include "juce_ComponentDeletionWatcher.h" | ||||
| #include "../graphics/geometry/juce_RectangleList.h" | |||||
| #include "mouse/juce_MouseInputSource.h" | |||||
| #include "mouse/juce_MouseListener.h" | |||||
| #include "mouse/juce_MouseEvent.h" | |||||
| //============================================================================== | //============================================================================== | ||||
| Desktop::Desktop() throw() | Desktop::Desktop() throw() | ||||
| : mouseClickCounter (0), | : mouseClickCounter (0), | ||||
| mouseMovedSignificantlySincePressed (false), | |||||
| kioskModeComponent (0) | kioskModeComponent (0) | ||||
| { | { | ||||
| zerostruct (mouseDowns); | |||||
| const int maxNumMice = 1; | |||||
| for (int i = maxNumMice; --i >= 0;) | |||||
| mouseSources.add (new MouseInputSource (i, true)); | |||||
| refreshMonitorSizes(); | refreshMonitorSizes(); | ||||
| } | } | ||||
| @@ -204,7 +209,7 @@ void Desktop::componentBroughtToFront (Component* const c) throw() | |||||
| //============================================================================== | //============================================================================== | ||||
| const Point<int> Desktop::getLastMouseDownPosition() throw() | const Point<int> Desktop::getLastMouseDownPosition() throw() | ||||
| { | { | ||||
| return getInstance().mouseDowns[0].position; | |||||
| return getInstance().getMainMouseSource().getLastMouseDownPosition(); | |||||
| } | } | ||||
| int Desktop::getMouseButtonClickCounter() throw() | int Desktop::getMouseButtonClickCounter() throw() | ||||
| @@ -217,59 +222,6 @@ void Desktop::incrementMouseClickCounter() throw() | |||||
| ++mouseClickCounter; | ++mouseClickCounter; | ||||
| } | } | ||||
| const Time Desktop::getLastMouseDownTime() const throw() | |||||
| { | |||||
| return Time (mouseDowns[0].time); | |||||
| } | |||||
| void Desktop::registerMouseDown (const Point<int>& position, int64 time, Component* component) throw() | |||||
| { | |||||
| for (int i = numElementsInArray (mouseDowns); --i > 0;) | |||||
| mouseDowns[i] = mouseDowns[i - 1]; | |||||
| mouseDowns[0].position = position; | |||||
| mouseDowns[0].time = time; | |||||
| mouseDowns[0].component = component; | |||||
| mouseMovedSignificantlySincePressed = false; | |||||
| } | |||||
| void Desktop::registerMouseDrag (const Point<int>& position) throw() | |||||
| { | |||||
| mouseMovedSignificantlySincePressed | |||||
| = mouseMovedSignificantlySincePressed | |||||
| || abs (mouseDowns[0].position.getX() - position.getX()) >= 4 | |||||
| || abs (mouseDowns[0].position.getY() - position.getY()) >= 4; | |||||
| } | |||||
| int Desktop::getNumberOfMultipleClicks() const throw() | |||||
| { | |||||
| int numClicks = 0; | |||||
| if (mouseDowns[0].time != 0) | |||||
| { | |||||
| if (! mouseMovedSignificantlySincePressed) | |||||
| ++numClicks; | |||||
| for (int i = 1; i < numElementsInArray (mouseDowns); ++i) | |||||
| { | |||||
| if (mouseDowns[0].time - mouseDowns[i].time | |||||
| < (int) (MouseEvent::getDoubleClickTimeout() * (1.0 + 0.25 * (i - 1))) | |||||
| && abs (mouseDowns[0].position.getX() - mouseDowns[i].position.getX()) < 8 | |||||
| && abs (mouseDowns[0].position.getY() - mouseDowns[i].position.getY()) < 8 | |||||
| && mouseDowns[0].component == mouseDowns[i].component) | |||||
| { | |||||
| ++numClicks; | |||||
| } | |||||
| else | |||||
| { | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| return numClicks; | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| void Desktop::addGlobalMouseListener (MouseListener* const listener) throw() | void Desktop::addGlobalMouseListener (MouseListener* const listener) throw() | ||||
| { | { | ||||
| @@ -339,7 +291,7 @@ void Desktop::sendMouseMove() | |||||
| 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 (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;) | for (int i = mouseListeners.size(); --i >= 0;) | ||||
| @@ -27,10 +27,16 @@ | |||||
| #define __JUCE_DESKTOP_JUCEHEADER__ | #define __JUCE_DESKTOP_JUCEHEADER__ | ||||
| #include "juce_Component.h" | #include "juce_Component.h" | ||||
| #include "../../core/juce_Time.h" | |||||
| #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_SortedSet.h" | ||||
| #include "../../containers/juce_OwnedArray.h" | |||||
| #include "../graphics/geometry/juce_RectangleList.h" | |||||
| class MouseInputSource; | |||||
| class MouseInputSourceInternal; | |||||
| class MouseListener; | |||||
| //============================================================================== | //============================================================================== | ||||
| @@ -233,6 +239,9 @@ public: | |||||
| /** True if the OS supports semitransparent windows */ | /** True if the OS supports semitransparent windows */ | ||||
| static bool canUseSemiTransparentWindows() throw(); | static bool canUseSemiTransparentWindows() throw(); | ||||
| int getNumMouseInputSources() const throw() { return mouseSources.size(); } | |||||
| MouseInputSource* getMouseSource (int index) const throw() { return mouseSources [index]; } | |||||
| MouseInputSource& getMainMouseSource() const throw() { return *mouseSources.getUnchecked(0); } | |||||
| private: | private: | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -240,6 +249,8 @@ private: | |||||
| friend class Component; | friend class Component; | ||||
| friend class ComponentPeer; | friend class ComponentPeer; | ||||
| friend class MouseInputSource; | |||||
| friend class MouseInputSourceInternal; | |||||
| SortedSet <void*> mouseListeners, focusListeners; | SortedSet <void*> mouseListeners, focusListeners; | ||||
| Array <Component*> desktopComponents; | Array <Component*> desktopComponents; | ||||
| @@ -250,24 +261,12 @@ private: | |||||
| Array <Rectangle<int> > monitorCoordsClipped, monitorCoordsUnclipped; | Array <Rectangle<int> > monitorCoordsClipped, monitorCoordsUnclipped; | ||||
| OwnedArray <MouseInputSource> mouseSources; | |||||
| Point<int> lastFakeMouseMove; | Point<int> lastFakeMouseMove; | ||||
| int mouseClickCounter; | int mouseClickCounter; | ||||
| bool mouseMovedSignificantlySincePressed; | |||||
| struct RecentMouseDown | |||||
| { | |||||
| Point<int> position; | |||||
| int64 time; | |||||
| Component* component; | |||||
| }; | |||||
| RecentMouseDown mouseDowns[4]; | |||||
| void incrementMouseClickCounter() throw(); | void incrementMouseClickCounter() throw(); | ||||
| void registerMouseDown (const Point<int>& position, int64 time, Component* component) throw(); | |||||
| void registerMouseDrag (const Point<int>& position) throw(); | |||||
| const Time getLastMouseDownTime() const throw(); | |||||
| int getNumberOfMultipleClicks() const throw(); | |||||
| Component* kioskModeComponent; | Component* kioskModeComponent; | ||||
| Rectangle<int> kioskComponentOriginalBounds; | Rectangle<int> kioskComponentOriginalBounds; | ||||
| @@ -47,11 +47,11 @@ ModifierKeys& ModifierKeys::operator= (const ModifierKeys& other) throw() | |||||
| return *this; | return *this; | ||||
| } | } | ||||
| int ModifierKeys::currentModifierFlags = 0; | |||||
| ModifierKeys ModifierKeys::currentModifiers; | |||||
| const ModifierKeys ModifierKeys::getCurrentModifiers() throw() | const ModifierKeys ModifierKeys::getCurrentModifiers() throw() | ||||
| { | { | ||||
| return ModifierKeys (currentModifierFlags); | |||||
| return currentModifiers; | |||||
| } | } | ||||
| int ModifierKeys::getNumMouseButtonsDown() const throw() | int ModifierKeys::getNumMouseButtonsDown() const throw() | ||||
| @@ -151,11 +151,23 @@ public: | |||||
| allMouseButtonModifiers = leftButtonModifier | rightButtonModifier | middleButtonModifier, | allMouseButtonModifiers = leftButtonModifier | rightButtonModifier | middleButtonModifier, | ||||
| }; | }; | ||||
| //============================================================================== | |||||
| /** Returns a copy of only the mouse-button flags */ | |||||
| const ModifierKeys withOnlyMouseButtons() const throw() { return ModifierKeys (flags & allMouseButtonModifiers); } | |||||
| /** Returns a copy of only the non-mouse flags */ | |||||
| const ModifierKeys withoutMouseButtons() const throw() { return ModifierKeys (flags & ~allMouseButtonModifiers); } | |||||
| bool operator== (const ModifierKeys& other) const throw() { return flags == other.flags; } | |||||
| bool operator!= (const ModifierKeys& other) const throw() { return flags != other.flags; } | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Returns the raw flags for direct testing. */ | /** Returns the raw flags for direct testing. */ | ||||
| inline int getRawFlags() const throw() { return flags; } | inline int getRawFlags() const throw() { return flags; } | ||||
| inline const ModifierKeys withoutFlags (int rawFlagsToClear) const throw() { return ModifierKeys (flags & ~rawFlagsToClear); } | |||||
| inline const ModifierKeys withFlags (int rawFlagsToSet) const throw() { return ModifierKeys (flags | rawFlagsToSet); } | |||||
| /** Tests a combination of flags and returns true if any of them are set. */ | /** Tests a combination of flags and returns true if any of them are set. */ | ||||
| inline bool testFlags (const int flagsToTest) const throw() { return (flags & flagsToTest) != 0; } | inline bool testFlags (const int flagsToTest) const throw() { return (flags & flagsToTest) != 0; } | ||||
| @@ -187,9 +199,11 @@ private: | |||||
| //============================================================================== | //============================================================================== | ||||
| int flags; | int flags; | ||||
| static int currentModifierFlags; | |||||
| static ModifierKeys currentModifiers; | |||||
| friend class ComponentPeer; | friend class ComponentPeer; | ||||
| friend class MouseInputSource; | |||||
| friend class MouseInputSourceInternal; | |||||
| static void updateCurrentModifiers() throw(); | static void updateCurrentModifiers() throw(); | ||||
| }; | }; | ||||
| @@ -32,7 +32,8 @@ BEGIN_JUCE_NAMESPACE | |||||
| //============================================================================== | //============================================================================== | ||||
| MouseEvent::MouseEvent (const Point<int>& position, | |||||
| MouseEvent::MouseEvent (MouseInputSource& source_, | |||||
| const Point<int>& position, | |||||
| const ModifierKeys& mods_, | const ModifierKeys& mods_, | ||||
| Component* const originator, | Component* const originator, | ||||
| const Time& eventTime_, | const Time& eventTime_, | ||||
| @@ -46,6 +47,7 @@ MouseEvent::MouseEvent (const Point<int>& position, | |||||
| eventComponent (originator), | eventComponent (originator), | ||||
| originalComponent (originator), | originalComponent (originator), | ||||
| eventTime (eventTime_), | eventTime (eventTime_), | ||||
| source (source_), | |||||
| mouseDownPos (mouseDownPos_), | mouseDownPos (mouseDownPos_), | ||||
| mouseDownTime (mouseDownTime_), | mouseDownTime (mouseDownTime_), | ||||
| numberOfClicks (numberOfClicks_), | numberOfClicks (numberOfClicks_), | ||||
| @@ -57,6 +59,28 @@ MouseEvent::~MouseEvent() throw() | |||||
| { | { | ||||
| } | } | ||||
| //============================================================================== | |||||
| const MouseEvent MouseEvent::getEventRelativeTo (Component* const otherComponent) const throw() | |||||
| { | |||||
| if (otherComponent == 0) | |||||
| { | |||||
| jassertfalse | |||||
| return *this; | |||||
| } | |||||
| return MouseEvent (source, eventComponent->relativePositionToOtherComponent (otherComponent, getPosition()), | |||||
| mods, originalComponent, eventTime, | |||||
| eventComponent->relativePositionToOtherComponent (otherComponent, mouseDownPos), | |||||
| mouseDownTime, numberOfClicks, wasMovedSinceMouseDown); | |||||
| } | |||||
| const MouseEvent MouseEvent::withNewPosition (const Point<int>& newPosition) const throw() | |||||
| { | |||||
| return MouseEvent (source, newPosition, mods, originalComponent, | |||||
| eventTime, mouseDownPos, mouseDownTime, | |||||
| numberOfClicks, wasMovedSinceMouseDown); | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| bool MouseEvent::mouseWasClicked() const throw() | bool MouseEvent::mouseWasClicked() const throw() | ||||
| { | { | ||||
| @@ -90,8 +114,7 @@ int MouseEvent::getDistanceFromDragStartY() const throw() | |||||
| int MouseEvent::getDistanceFromDragStart() const throw() | int MouseEvent::getDistanceFromDragStart() const throw() | ||||
| { | { | ||||
| return roundToInt (juce_hypot (getDistanceFromDragStartX(), | |||||
| getDistanceFromDragStartY())); | |||||
| return mouseDownPos.getDistanceFrom (getPosition()); | |||||
| } | } | ||||
| int MouseEvent::getLengthOfMousePress() const throw() | int MouseEvent::getLengthOfMousePress() const throw() | ||||
| @@ -138,25 +161,6 @@ const Point<int> MouseEvent::getMouseDownScreenPosition() const | |||||
| return eventComponent->relativePositionToGlobal (mouseDownPos); | return eventComponent->relativePositionToGlobal (mouseDownPos); | ||||
| } | } | ||||
| //============================================================================== | |||||
| const MouseEvent MouseEvent::getEventRelativeTo (Component* const otherComponent) const throw() | |||||
| { | |||||
| if (otherComponent == 0) | |||||
| { | |||||
| jassertfalse | |||||
| return *this; | |||||
| } | |||||
| return MouseEvent (eventComponent->relativePositionToOtherComponent (otherComponent, Point<int> (x, y)), | |||||
| mods, | |||||
| originalComponent, | |||||
| eventTime, | |||||
| eventComponent->relativePositionToOtherComponent (otherComponent, mouseDownPos), | |||||
| mouseDownTime, | |||||
| numberOfClicks, | |||||
| wasMovedSinceMouseDown); | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| static int doubleClickTimeOutMs = 400; | static int doubleClickTimeOutMs = 400; | ||||
| @@ -27,6 +27,7 @@ | |||||
| #define __JUCE_MOUSEEVENT_JUCEHEADER__ | #define __JUCE_MOUSEEVENT_JUCEHEADER__ | ||||
| class Component; | class Component; | ||||
| class MouseInputSource; | |||||
| #include "../keyboard/juce_ModifierKeys.h" | #include "../keyboard/juce_ModifierKeys.h" | ||||
| #include "../../../core/juce_Time.h" | #include "../../../core/juce_Time.h" | ||||
| #include "../../graphics/geometry/juce_Point.h" | #include "../../graphics/geometry/juce_Point.h" | ||||
| @@ -47,6 +48,7 @@ public: | |||||
| Normally an application will never need to use this. | Normally an application will never need to use this. | ||||
| @param source the source that's invoking the event | |||||
| @param position the position of the mouse, relative to the component that is passed-in | @param position the position of the mouse, relative to the component that is passed-in | ||||
| @param modifiers the key modifiers at the time of the event | @param modifiers the key modifiers at the time of the event | ||||
| @param originator the component that the mouse event applies to | @param originator the component that the mouse event applies to | ||||
| @@ -60,7 +62,8 @@ public: | |||||
| @param numberOfClicks how many clicks, e.g. a double-click event will be 2, a triple-click will be 3, etc | @param numberOfClicks how many clicks, e.g. a double-click event will be 2, a triple-click will be 3, etc | ||||
| @param mouseWasDragged whether the mouse has been dragged significantly since the previous mouse-down | @param mouseWasDragged whether the mouse has been dragged significantly since the previous mouse-down | ||||
| */ | */ | ||||
| MouseEvent (const Point<int>& position, | |||||
| MouseEvent (MouseInputSource& source, | |||||
| const Point<int>& position, | |||||
| const ModifierKeys& modifiers, | const ModifierKeys& modifiers, | ||||
| Component* const originator, | Component* const originator, | ||||
| const Time& eventTime, | const Time& eventTime, | ||||
| @@ -78,14 +81,14 @@ public: | |||||
| This value is relative to the top-left of the component to which the | This value is relative to the top-left of the component to which the | ||||
| event applies (as indicated by the MouseEvent::eventComponent field). | event applies (as indicated by the MouseEvent::eventComponent field). | ||||
| */ | */ | ||||
| int x; | |||||
| const int x; | |||||
| /** The y-position of the mouse when the event occurred. | /** The y-position of the mouse when the event occurred. | ||||
| This value is relative to the top-left of the component to which the | This value is relative to the top-left of the component to which the | ||||
| event applies (as indicated by the MouseEvent::eventComponent field). | event applies (as indicated by the MouseEvent::eventComponent field). | ||||
| */ | */ | ||||
| int y; | |||||
| const int y; | |||||
| /** The key modifiers associated with the event. | /** The key modifiers associated with the event. | ||||
| @@ -95,7 +98,7 @@ public: | |||||
| When used for mouse-up events, this will indicate the state of the mouse buttons | When used for mouse-up events, this will indicate the state of the mouse buttons | ||||
| just before they were released, so that you can tell which button they let go of. | just before they were released, so that you can tell which button they let go of. | ||||
| */ | */ | ||||
| ModifierKeys mods; | |||||
| const ModifierKeys mods; | |||||
| /** The component that this event applies to. | /** The component that this event applies to. | ||||
| @@ -110,7 +113,7 @@ public: | |||||
| @see originalComponent | @see originalComponent | ||||
| */ | */ | ||||
| Component* eventComponent; | |||||
| Component* const eventComponent; | |||||
| /** The component that the event first occurred on. | /** The component that the event first occurred on. | ||||
| @@ -119,11 +122,15 @@ public: | |||||
| @see eventComponent | @see eventComponent | ||||
| */ | */ | ||||
| Component* originalComponent; | |||||
| Component* const originalComponent; | |||||
| /** The time that this mouse-event occurred. | /** The time that this mouse-event occurred. | ||||
| */ | */ | ||||
| Time eventTime; | |||||
| const Time eventTime; | |||||
| /** The source device that generated this event. | |||||
| */ | |||||
| MouseInputSource& source; | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Returns the x co-ordinate of the last place that a mouse was pressed. | /** Returns the x co-ordinate of the last place that a mouse was pressed. | ||||
| @@ -218,7 +225,7 @@ public: | |||||
| The co-ordinates are relative to the top-left of the main monitor. | The co-ordinates are relative to the top-left of the main monitor. | ||||
| @see getMouseDownScreenX, Desktop::getMousePosition | |||||
| @see getScreenPosition | |||||
| */ | */ | ||||
| int getScreenX() const; | int getScreenX() const; | ||||
| @@ -226,7 +233,7 @@ public: | |||||
| The co-ordinates are relative to the top-left of the main monitor. | The co-ordinates are relative to the top-left of the main monitor. | ||||
| @see getMouseDownScreenY, Desktop::getMousePosition | |||||
| @see getScreenPosition | |||||
| */ | */ | ||||
| int getScreenY() const; | int getScreenY() const; | ||||
| @@ -234,7 +241,7 @@ public: | |||||
| The co-ordinates are relative to the top-left of the main monitor. | The co-ordinates are relative to the top-left of the main monitor. | ||||
| @see getMouseDownScreenY, Desktop::getMousePosition | |||||
| @see getMouseDownScreenPosition | |||||
| */ | */ | ||||
| const Point<int> getScreenPosition() const; | const Point<int> getScreenPosition() const; | ||||
| @@ -242,7 +249,7 @@ public: | |||||
| The co-ordinates are relative to the top-left of the main monitor. | The co-ordinates are relative to the top-left of the main monitor. | ||||
| @see getScreenX, Desktop::getMousePosition | |||||
| @see getMouseDownScreenPosition | |||||
| */ | */ | ||||
| int getMouseDownScreenX() const; | int getMouseDownScreenX() const; | ||||
| @@ -250,7 +257,7 @@ public: | |||||
| The co-ordinates are relative to the top-left of the main monitor. | The co-ordinates are relative to the top-left of the main monitor. | ||||
| @see getScreenY, Desktop::getMousePosition | |||||
| @see getMouseDownScreenPosition | |||||
| */ | */ | ||||
| int getMouseDownScreenY() const; | int getMouseDownScreenY() const; | ||||
| @@ -258,7 +265,7 @@ public: | |||||
| The co-ordinates are relative to the top-left of the main monitor. | The co-ordinates are relative to the top-left of the main monitor. | ||||
| @see getScreenY, Desktop::getMousePosition | |||||
| @see getScreenPosition | |||||
| */ | */ | ||||
| const Point<int> getMouseDownScreenPosition() const; | const Point<int> getMouseDownScreenPosition() const; | ||||
| @@ -270,6 +277,12 @@ public: | |||||
| */ | */ | ||||
| const MouseEvent getEventRelativeTo (Component* const otherComponent) const throw(); | const MouseEvent getEventRelativeTo (Component* const otherComponent) const throw(); | ||||
| /** Creates a copy of this event with a different position. | |||||
| All other members of the event object are the same, but the x and y are | |||||
| replaced with these new values. | |||||
| */ | |||||
| const MouseEvent withNewPosition (const Point<int>& newPosition) const throw(); | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Changes the application-wide setting for the double-click time limit. | /** Changes the application-wide setting for the double-click time limit. | ||||
| @@ -294,10 +307,12 @@ public: | |||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| private: | private: | ||||
| Point<int> mouseDownPos; | |||||
| Time mouseDownTime; | |||||
| int numberOfClicks; | |||||
| bool wasMovedSinceMouseDown; | |||||
| const Point<int> mouseDownPos; | |||||
| const Time mouseDownTime; | |||||
| const int numberOfClicks; | |||||
| const bool wasMovedSinceMouseDown; | |||||
| MouseEvent& operator= (const MouseEvent&); | |||||
| }; | }; | ||||
| @@ -29,6 +29,7 @@ BEGIN_JUCE_NAMESPACE | |||||
| #include "../juce_Component.h" | #include "../juce_Component.h" | ||||
| #include "juce_MouseHoverDetector.h" | #include "juce_MouseHoverDetector.h" | ||||
| #include "juce_MouseEvent.h" | |||||
| //============================================================================== | //============================================================================== | ||||
| @@ -0,0 +1,370 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| 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. | |||||
| ============================================================================== | |||||
| */ | |||||
| #include "../../../core/juce_StandardHeader.h" | |||||
| BEGIN_JUCE_NAMESPACE | |||||
| #include "juce_MouseInputSource.h" | |||||
| #include "juce_MouseEvent.h" | |||||
| #include "../juce_Component.h" | |||||
| #include "../juce_ComponentDeletionWatcher.h" | |||||
| #include "../../../events/juce_AsyncUpdater.h" | |||||
| //============================================================================== | |||||
| class MouseInputSourceInternal : public AsyncUpdater | |||||
| { | |||||
| public: | |||||
| MouseInputSourceInternal (MouseInputSource& source_, const int index_, const bool isMouseDevice_) | |||||
| : source (source_), index (index_), isMouseDevice (isMouseDevice_), lastPeer (0), lastTime (0) | |||||
| { | |||||
| zerostruct (mouseDowns); | |||||
| } | |||||
| ~MouseInputSourceInternal() | |||||
| { | |||||
| } | |||||
| bool isDragging() const throw() | |||||
| { | |||||
| return buttonState.isAnyMouseButtonDown(); | |||||
| } | |||||
| Component* getComponentUnderMouse() const | |||||
| { | |||||
| return componentUnderMouse != 0 ? const_cast<Component*> (componentUnderMouse->getComponent()) : 0; | |||||
| } | |||||
| const ModifierKeys getCurrentModifiers() const | |||||
| { | |||||
| return ModifierKeys::getCurrentModifiers().withoutMouseButtons().withFlags (buttonState.getRawFlags()); | |||||
| } | |||||
| ComponentPeer* getPeer() | |||||
| { | |||||
| if (! ComponentPeer::isValidPeer (lastPeer)) | |||||
| lastPeer = 0; | |||||
| return lastPeer; | |||||
| } | |||||
| Component* findComponentAt (const Point<int>& screenPos) | |||||
| { | |||||
| ComponentPeer* const peer = getPeer(); | |||||
| if (peer != 0) | |||||
| { | |||||
| Component* const comp = peer->getComponent(); | |||||
| const Point<int> relativePos (comp->globalPositionToRelative (screenPos)); | |||||
| // (the contains() call is needed to test for overlapping desktop windows) | |||||
| if (comp->contains (relativePos.getX(), relativePos.getY())) | |||||
| return comp->getComponentAt (relativePos); | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| void setButtons (const Point<int>& screenPos, const int64 time, const ModifierKeys& newButtonState) | |||||
| { | |||||
| if (buttonState != newButtonState) | |||||
| { | |||||
| // (ignore secondary clicks when there's already a button down) | |||||
| if (buttonState.isAnyMouseButtonDown() == newButtonState.isAnyMouseButtonDown()) | |||||
| { | |||||
| buttonState = newButtonState; | |||||
| return; | |||||
| } | |||||
| if (buttonState.isAnyMouseButtonDown()) | |||||
| { | |||||
| Component* const current = getComponentUnderMouse(); | |||||
| if (current != 0) | |||||
| current->internalMouseUp (source, current->globalPositionToRelative (screenPos), | |||||
| time, getCurrentModifiers()); | |||||
| } | |||||
| buttonState = newButtonState; | |||||
| if (buttonState.isAnyMouseButtonDown()) | |||||
| { | |||||
| Desktop::getInstance().incrementMouseClickCounter(); | |||||
| Component* const current = getComponentUnderMouse(); | |||||
| if (current != 0) | |||||
| { | |||||
| registerMouseDown (screenPos, time, current); | |||||
| current->internalMouseDown (source, current->globalPositionToRelative (screenPos), time); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| void setComponentUnderMouse (Component* const newComponent, const Point<int>& screenPos, const int64 time) | |||||
| { | |||||
| Component* current = getComponentUnderMouse(); | |||||
| if (newComponent != current) | |||||
| { | |||||
| ScopedPointer<ComponentDeletionWatcher> newCompWatcher (newComponent != 0 ? new ComponentDeletionWatcher (newComponent) : 0); | |||||
| const ModifierKeys originalButtonState (buttonState); | |||||
| if (current != 0) | |||||
| { | |||||
| setButtons (screenPos, time, ModifierKeys()); | |||||
| current->internalMouseExit (source, current->globalPositionToRelative (screenPos), time); | |||||
| buttonState = originalButtonState; | |||||
| } | |||||
| componentUnderMouse = newCompWatcher; | |||||
| current = getComponentUnderMouse(); | |||||
| Component::componentUnderMouse = current; | |||||
| if (current != 0) | |||||
| current->internalMouseEnter (source, current->globalPositionToRelative (screenPos), time); | |||||
| setButtons (screenPos, time, originalButtonState); | |||||
| } | |||||
| } | |||||
| void setPeer (ComponentPeer* const newPeer, const Point<int>& screenPos, const int64 time) | |||||
| { | |||||
| ModifierKeys::updateCurrentModifiers(); | |||||
| if (newPeer != lastPeer) | |||||
| { | |||||
| setComponentUnderMouse (0, screenPos, time); | |||||
| lastPeer = newPeer; | |||||
| setComponentUnderMouse (findComponentAt (screenPos), screenPos, time); | |||||
| } | |||||
| } | |||||
| void setScreenPos (const Point<int>& newScreenPos, const int64 time, const bool forceUpdate) | |||||
| { | |||||
| if (! isDragging()) | |||||
| setComponentUnderMouse (findComponentAt (newScreenPos), newScreenPos, time); | |||||
| if (newScreenPos != lastScreenPos || forceUpdate) | |||||
| { | |||||
| cancelPendingUpdate(); | |||||
| lastScreenPos = newScreenPos; | |||||
| Component* const current = getComponentUnderMouse(); | |||||
| if (current != 0) | |||||
| { | |||||
| const Point<int> pos (current->globalPositionToRelative (lastScreenPos)); | |||||
| if (isDragging()) | |||||
| { | |||||
| registerMouseDrag (newScreenPos); | |||||
| current->internalMouseDrag (source, pos, time); | |||||
| } | |||||
| else | |||||
| { | |||||
| current->internalMouseMove (source, pos, time); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| void handleEvent (ComponentPeer* const newPeer, const Point<int>& positionWithinPeer, const int64 time, const ModifierKeys& newMods) | |||||
| { | |||||
| jassert (newPeer != 0); | |||||
| lastTime = time; | |||||
| const Point<int> screenPos (newPeer->relativePositionToGlobal (positionWithinPeer)); | |||||
| if (isDragging() && newMods.isAnyMouseButtonDown()) | |||||
| { | |||||
| setScreenPos (screenPos, time, false); | |||||
| } | |||||
| else | |||||
| { | |||||
| setPeer (newPeer, screenPos, time); | |||||
| ComponentPeer* peer = getPeer(); | |||||
| if (peer != 0) | |||||
| { | |||||
| setButtons (screenPos, time, newMods); | |||||
| peer = getPeer(); | |||||
| if (peer != 0) | |||||
| setScreenPos (peer->relativePositionToGlobal (positionWithinPeer), time, false); | |||||
| } | |||||
| } | |||||
| } | |||||
| void handleWheel (ComponentPeer* const peer, const Point<int>& positionWithinPeer, int64 time, float x, float y) | |||||
| { | |||||
| jassert (peer != 0); | |||||
| lastTime = time; | |||||
| const Point<int> screenPos (peer->relativePositionToGlobal (positionWithinPeer)); | |||||
| setPeer (peer, screenPos, time); | |||||
| setScreenPos (screenPos, time, false); | |||||
| triggerFakeMove(); | |||||
| if (! isDragging()) | |||||
| { | |||||
| Component* current = getComponentUnderMouse(); | |||||
| if (current != 0) | |||||
| current->internalMouseWheel (source, current->globalPositionToRelative (screenPos), time, x, y); | |||||
| } | |||||
| } | |||||
| const Time getLastMouseDownTime() const throw() | |||||
| { | |||||
| return Time (mouseDowns[0].time); | |||||
| } | |||||
| const Point<int> getLastMouseDownPosition() const throw() | |||||
| { | |||||
| return mouseDowns[0].position; | |||||
| } | |||||
| int getNumberOfMultipleClicks() const throw() | |||||
| { | |||||
| int numClicks = 0; | |||||
| if (mouseDowns[0].time != 0) | |||||
| { | |||||
| if (! mouseMovedSignificantlySincePressed) | |||||
| ++numClicks; | |||||
| for (int i = 1; i < numElementsInArray (mouseDowns); ++i) | |||||
| { | |||||
| if (mouseDowns[0].time - mouseDowns[i].time < (int) (MouseEvent::getDoubleClickTimeout() * (1.0 + 0.25 * (i - 1))) | |||||
| && abs (mouseDowns[0].position.getX() - mouseDowns[i].position.getX()) < 8 | |||||
| && abs (mouseDowns[0].position.getY() - mouseDowns[i].position.getY()) < 8 | |||||
| && mouseDowns[0].component == mouseDowns[i].component) | |||||
| { | |||||
| ++numClicks; | |||||
| } | |||||
| else | |||||
| { | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| return numClicks; | |||||
| } | |||||
| bool hasMouseMovedSignificantlySincePressed() const throw() | |||||
| { | |||||
| return mouseMovedSignificantlySincePressed | |||||
| || lastTime > mouseDowns[0].time + 300; | |||||
| } | |||||
| void triggerFakeMove() | |||||
| { | |||||
| triggerAsyncUpdate(); | |||||
| } | |||||
| void handleAsyncUpdate() | |||||
| { | |||||
| setScreenPos (Desktop::getMousePosition(), Time::currentTimeMillis(), true); | |||||
| } | |||||
| int index; | |||||
| bool isMouseDevice; | |||||
| Point<int> lastScreenPos; | |||||
| ModifierKeys buttonState; | |||||
| private: | |||||
| MouseInputSource& source; | |||||
| ScopedPointer<ComponentDeletionWatcher> componentUnderMouse; | |||||
| ComponentPeer* lastPeer; | |||||
| struct RecentMouseDown | |||||
| { | |||||
| Point<int> position; | |||||
| int64 time; | |||||
| Component* component; | |||||
| }; | |||||
| RecentMouseDown mouseDowns[4]; | |||||
| bool mouseMovedSignificantlySincePressed; | |||||
| int64 lastTime; | |||||
| void registerMouseDown (const Point<int>& screenPos, const int64 time, Component* const component) throw() | |||||
| { | |||||
| for (int i = numElementsInArray (mouseDowns); --i > 0;) | |||||
| mouseDowns[i] = mouseDowns[i - 1]; | |||||
| mouseDowns[0].position = screenPos; | |||||
| mouseDowns[0].time = time; | |||||
| mouseDowns[0].component = component; | |||||
| mouseMovedSignificantlySincePressed = false; | |||||
| } | |||||
| void registerMouseDrag (const Point<int>& screenPos) throw() | |||||
| { | |||||
| mouseMovedSignificantlySincePressed = mouseMovedSignificantlySincePressed | |||||
| || mouseDowns[0].position.getDistanceFrom (screenPos) >= 4; | |||||
| } | |||||
| }; | |||||
| //============================================================================== | |||||
| MouseInputSource::MouseInputSource (const int index, const bool isMouseDevice) | |||||
| { | |||||
| pimpl = new MouseInputSourceInternal (*this, index, isMouseDevice); | |||||
| } | |||||
| MouseInputSource::~MouseInputSource() | |||||
| { | |||||
| } | |||||
| bool MouseInputSource::isMouse() const { return pimpl->isMouseDevice; } | |||||
| bool MouseInputSource::isTouch() const { return ! pimpl->isMouseDevice; } | |||||
| bool MouseInputSource::canHover() const { return pimpl->isMouseDevice; } | |||||
| bool MouseInputSource::hasMouseWheel() const { return pimpl->isMouseDevice; } | |||||
| int MouseInputSource::getIndex() const { return pimpl->index; } | |||||
| bool MouseInputSource::isDragging() const { return pimpl->isDragging(); } | |||||
| const Point<int> MouseInputSource::getScreenPosition() const { return pimpl->lastScreenPos; } | |||||
| const ModifierKeys MouseInputSource::getCurrentModifiers() const { return pimpl->getCurrentModifiers(); } | |||||
| Component* MouseInputSource::getComponentUnderMouse() const { return pimpl->getComponentUnderMouse(); } | |||||
| void MouseInputSource::triggerFakeMove() const { pimpl->triggerFakeMove(); } | |||||
| int MouseInputSource::getNumberOfMultipleClicks() const throw() { return pimpl->getNumberOfMultipleClicks(); } | |||||
| const Time MouseInputSource::getLastMouseDownTime() const throw() { return pimpl->getLastMouseDownTime(); } | |||||
| const Point<int> MouseInputSource::getLastMouseDownPosition() const throw() { return pimpl->getLastMouseDownPosition(); } | |||||
| bool MouseInputSource::hasMouseMovedSignificantlySincePressed() const throw() { return pimpl->hasMouseMovedSignificantlySincePressed(); } | |||||
| void MouseInputSource::handleEvent (ComponentPeer* peer, const Point<int>& positionWithinPeer, const int64 time, const ModifierKeys& mods) | |||||
| { | |||||
| pimpl->handleEvent (peer, positionWithinPeer, time, mods.withOnlyMouseButtons()); | |||||
| } | |||||
| void MouseInputSource::handleWheel (ComponentPeer* const peer, const Point<int>& positionWithinPeer, const int64 time, const float x, const float y) | |||||
| { | |||||
| pimpl->handleWheel (peer, positionWithinPeer, time, x, y); | |||||
| } | |||||
| END_JUCE_NAMESPACE | |||||
| @@ -0,0 +1,85 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| 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_MOUSEEVENT_JUCEHEADER__x | |||||
| #define __JUCE_MOUSEEVENT_JUCEHEADER__x | |||||
| class Component; | |||||
| class ComponentPeer; | |||||
| class MouseInputSourceInternal; | |||||
| #include "../keyboard/juce_ModifierKeys.h" | |||||
| #include "../../../core/juce_Time.h" | |||||
| #include "../../../containers/juce_ScopedPointer.h" | |||||
| #include "../../graphics/geometry/juce_Point.h" | |||||
| #include "../juce_Desktop.h" | |||||
| //============================================================================== | |||||
| /** | |||||
| */ | |||||
| 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(); | |||||
| //============================================================================== | |||||
| 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 MouseInputSourceInternal; | |||||
| ScopedPointer<MouseInputSourceInternal> pimpl; | |||||
| friend class Desktop; | |||||
| friend class ComponentPeer; | |||||
| MouseInputSource (const MouseInputSource&); | |||||
| MouseInputSource& operator= (const MouseInputSource&); | |||||
| }; | |||||
| #endif // __JUCE_MOUSEEVENT_JUCEHEADER__ | |||||
| @@ -26,8 +26,7 @@ | |||||
| #ifndef __JUCE_MOUSELISTENER_JUCEHEADER__ | #ifndef __JUCE_MOUSELISTENER_JUCEHEADER__ | ||||
| #define __JUCE_MOUSELISTENER_JUCEHEADER__ | #define __JUCE_MOUSELISTENER_JUCEHEADER__ | ||||
| #include "juce_MouseEvent.h" | |||||
| class MouseEvent; | |||||
| //============================================================================== | //============================================================================== | ||||
| /** | /** | ||||
| @@ -116,6 +116,7 @@ public: | |||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| private: | private: | ||||
| class ActiveXControlData; | |||||
| friend class ActiveXControlData; | friend class ActiveXControlData; | ||||
| void* control; | void* control; | ||||
| bool mouseEventsAllowed; | bool mouseEventsAllowed; | ||||
| @@ -110,10 +110,10 @@ public: | |||||
| roundToInt (p.getY() / zoom)); | roundToInt (p.getY() / zoom)); | ||||
| } | } | ||||
| bool contains (int x, int y, bool) const | |||||
| bool contains (const Point<int>& position, bool) const | |||||
| { | { | ||||
| return ((unsigned int) x) < (unsigned int) magnifierComp->getWidth() | |||||
| && ((unsigned int) y) < (unsigned int) magnifierComp->getHeight(); | |||||
| return ((unsigned int) position.getX()) < (unsigned int) magnifierComp->getWidth() | |||||
| && ((unsigned int) position.getY()) < (unsigned int) magnifierComp->getHeight(); | |||||
| } | } | ||||
| void repaint (int x, int y, int w, int h) | void repaint (int x, int y, int w, int h) | ||||
| @@ -193,7 +193,8 @@ MagnifierComponent::MagnifierComponent (Component* const content_, | |||||
| scaleFactor (0.0), | scaleFactor (0.0), | ||||
| peer (0), | peer (0), | ||||
| deleteContent (deleteContentCompWhenNoLongerNeeded), | deleteContent (deleteContentCompWhenNoLongerNeeded), | ||||
| quality (Graphics::lowResamplingQuality) | |||||
| quality (Graphics::lowResamplingQuality), | |||||
| mouseSource (0, true) | |||||
| { | { | ||||
| holderComp = new PeerHolderComp (this); | holderComp = new PeerHolderComp (this); | ||||
| setScaleFactor (1.0); | setScaleFactor (1.0); | ||||
| @@ -285,48 +286,48 @@ void MagnifierComponent::childBoundsChanged (Component* c) | |||||
| roundToInt (c->getHeight() * scaleFactor)); | roundToInt (c->getHeight() * scaleFactor)); | ||||
| } | } | ||||
| void MagnifierComponent::mouseDown (const MouseEvent& e) | |||||
| void MagnifierComponent::passOnMouseEventToPeer (const MouseEvent& e) | |||||
| { | { | ||||
| if (peer != 0) | if (peer != 0) | ||||
| peer->handleMouseDown (Point<int> (scaleInt (e.x), scaleInt (e.y)), e.eventTime.toMilliseconds()); | |||||
| mouseSource.handleEvent (peer, Point<int> (scaleInt (e.x), scaleInt (e.y)), | |||||
| e.eventTime.toMilliseconds(), ModifierKeys::getCurrentModifiers()); | |||||
| } | |||||
| void MagnifierComponent::mouseDown (const MouseEvent& e) | |||||
| { | |||||
| passOnMouseEventToPeer (e); | |||||
| } | } | ||||
| void MagnifierComponent::mouseUp (const MouseEvent& e) | void MagnifierComponent::mouseUp (const MouseEvent& e) | ||||
| { | { | ||||
| if (peer != 0) | |||||
| peer->handleMouseUp (e.mods.getRawFlags(), Point<int> (scaleInt (e.x), scaleInt (e.y)), e.eventTime.toMilliseconds()); | |||||
| passOnMouseEventToPeer (e); | |||||
| } | } | ||||
| void MagnifierComponent::mouseDrag (const MouseEvent& e) | void MagnifierComponent::mouseDrag (const MouseEvent& e) | ||||
| { | { | ||||
| if (peer != 0) | |||||
| peer->handleMouseDrag (Point<int> (scaleInt (e.x), scaleInt (e.y)), e.eventTime.toMilliseconds()); | |||||
| passOnMouseEventToPeer (e); | |||||
| } | } | ||||
| void MagnifierComponent::mouseMove (const MouseEvent& e) | void MagnifierComponent::mouseMove (const MouseEvent& e) | ||||
| { | { | ||||
| if (peer != 0) | |||||
| peer->handleMouseMove (Point<int> (scaleInt (e.x), scaleInt (e.y)), e.eventTime.toMilliseconds()); | |||||
| passOnMouseEventToPeer (e); | |||||
| } | } | ||||
| void MagnifierComponent::mouseEnter (const MouseEvent& e) | void MagnifierComponent::mouseEnter (const MouseEvent& e) | ||||
| { | { | ||||
| if (peer != 0) | |||||
| peer->handleMouseEnter (Point<int> (scaleInt (e.x), scaleInt (e.y)), e.eventTime.toMilliseconds()); | |||||
| passOnMouseEventToPeer (e); | |||||
| } | } | ||||
| void MagnifierComponent::mouseExit (const MouseEvent& e) | void MagnifierComponent::mouseExit (const MouseEvent& e) | ||||
| { | { | ||||
| if (peer != 0) | |||||
| peer->handleMouseExit (Point<int> (scaleInt (e.x), scaleInt (e.y)), e.eventTime.toMilliseconds()); | |||||
| passOnMouseEventToPeer (e); | |||||
| } | } | ||||
| void MagnifierComponent::mouseWheelMove (const MouseEvent& e, float ix, float iy) | void MagnifierComponent::mouseWheelMove (const MouseEvent& e, float ix, float iy) | ||||
| { | { | ||||
| if (peer != 0) | if (peer != 0) | ||||
| peer->handleMouseWheel (roundToInt (ix * 256.0f), | |||||
| roundToInt (iy * 256.0f), | |||||
| e.eventTime.toMilliseconds()); | |||||
| peer->handleMouseWheel (Point<int> (scaleInt (e.x), scaleInt (e.y)), e.eventTime.toMilliseconds(), | |||||
| ix * 256.0f, iy * 256.0f); | |||||
| else | else | ||||
| Component::mouseWheelMove (e, ix, iy); | Component::mouseWheelMove (e, ix, iy); | ||||
| } | } | ||||
| @@ -27,6 +27,7 @@ | |||||
| #define __JUCE_MAGNIFIERCOMPONENT_JUCEHEADER__ | #define __JUCE_MAGNIFIERCOMPONENT_JUCEHEADER__ | ||||
| #include "../juce_Component.h" | #include "../juce_Component.h" | ||||
| #include "../mouse/juce_MouseInputSource.h" | |||||
| //============================================================================== | //============================================================================== | ||||
| @@ -100,6 +101,7 @@ private: | |||||
| ComponentPeer* peer; | ComponentPeer* peer; | ||||
| bool deleteContent; | bool deleteContent; | ||||
| Graphics::ResamplingQuality quality; | Graphics::ResamplingQuality quality; | ||||
| MouseInputSource mouseSource; | |||||
| //============================================================================== | //============================================================================== | ||||
| void paint (Graphics& g); | void paint (Graphics& g); | ||||
| @@ -111,6 +113,7 @@ private: | |||||
| void mouseExit (const MouseEvent& e); | void mouseExit (const MouseEvent& e); | ||||
| void mouseWheelMove (const MouseEvent& e, float, float); | void mouseWheelMove (const MouseEvent& e, float, float); | ||||
| void passOnMouseEventToPeer (const MouseEvent& e); | |||||
| int scaleInt (const int n) const; | int scaleInt (const int n) const; | ||||
| MagnifierComponent (const MagnifierComponent&); | MagnifierComponent (const MagnifierComponent&); | ||||
| @@ -36,12 +36,12 @@ BEGIN_JUCE_NAMESPACE | |||||
| #include "../../../core/juce_Random.h" | #include "../../../core/juce_Random.h" | ||||
| #include "../layout/juce_ComponentBoundsConstrainer.h" | #include "../layout/juce_ComponentBoundsConstrainer.h" | ||||
| #include "../mouse/juce_FileDragAndDropTarget.h" | #include "../mouse/juce_FileDragAndDropTarget.h" | ||||
| #include "../mouse/juce_MouseInputSource.h" | |||||
| //#define JUCE_ENABLE_REPAINT_DEBUGGING 1 | //#define JUCE_ENABLE_REPAINT_DEBUGGING 1 | ||||
| //============================================================================== | //============================================================================== | ||||
| static const int fakeMouseMoveMessage = 0x7fff00ff; | |||||
| static VoidArray heavyweightPeers; | static VoidArray heavyweightPeers; | ||||
| @@ -102,203 +102,14 @@ void ComponentPeer::updateCurrentModifiers() throw() | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| void ComponentPeer::handleMouseEnter (const Point<int>& position, const int64 time) | |||||
| void ComponentPeer::handleMouseEvent (const Point<int>& positionWithinPeer, const ModifierKeys& newMods, const int64 time) | |||||
| { | { | ||||
| jassert (component->isValidComponent()); | |||||
| updateCurrentModifiers(); | |||||
| Component* c = component->getComponentAt (position); | |||||
| const ComponentDeletionWatcher deletionChecker (component); | |||||
| if (c != Component::componentUnderMouse && Component::componentUnderMouse != 0) | |||||
| { | |||||
| jassert (Component::componentUnderMouse->isValidComponent()); | |||||
| const Point<int> relPos (component->relativePositionToOtherComponent (Component::componentUnderMouse, position)); | |||||
| Component::componentUnderMouse->internalMouseExit (relPos.getX(), relPos.getY(), time); | |||||
| Component::componentUnderMouse = 0; | |||||
| if (deletionChecker.hasBeenDeleted()) | |||||
| return; | |||||
| c = component->getComponentAt (position); | |||||
| } | |||||
| Component::componentUnderMouse = c; | |||||
| if (Component::componentUnderMouse != 0) | |||||
| { | |||||
| const Point<int> relPos (component->relativePositionToOtherComponent (Component::componentUnderMouse, position)); | |||||
| Component::componentUnderMouse->internalMouseEnter (relPos.getX(), relPos.getY(), time); | |||||
| } | |||||
| Desktop::getInstance().getMainMouseSource().handleEvent (this, positionWithinPeer, time, newMods); | |||||
| } | } | ||||
| void ComponentPeer::handleMouseMove (const Point<int>& position, const int64 time) | |||||
| void ComponentPeer::handleMouseWheel (const Point<int>& positionWithinPeer, const int64 time, float x, float y) | |||||
| { | { | ||||
| jassert (component->isValidComponent()); | |||||
| updateCurrentModifiers(); | |||||
| fakeMouseMessageSent = false; | |||||
| const ComponentDeletionWatcher deletionChecker (component); | |||||
| Component* c = component->getComponentAt (position); | |||||
| if (c != Component::componentUnderMouse) | |||||
| { | |||||
| if (Component::componentUnderMouse != 0) | |||||
| { | |||||
| const Point<int> relPos (component->relativePositionToOtherComponent (Component::componentUnderMouse, position)); | |||||
| Component::componentUnderMouse->internalMouseExit (relPos.getX(), relPos.getY(), time); | |||||
| Component::componentUnderMouse = 0; | |||||
| if (deletionChecker.hasBeenDeleted()) | |||||
| return; // if this window has just been deleted.. | |||||
| c = component->getComponentAt (position); | |||||
| } | |||||
| Component::componentUnderMouse = c; | |||||
| if (c != 0) | |||||
| { | |||||
| const Point<int> relPos (component->relativePositionToOtherComponent (c, position)); | |||||
| c->internalMouseEnter (relPos.getX(), relPos.getY(), time); | |||||
| if (deletionChecker.hasBeenDeleted()) | |||||
| return; // if this window has just been deleted.. | |||||
| } | |||||
| } | |||||
| if (Component::componentUnderMouse != 0) | |||||
| { | |||||
| const Point<int> relPos (component->relativePositionToOtherComponent (Component::componentUnderMouse, position)); | |||||
| Component::componentUnderMouse->internalMouseMove (relPos.getX(), relPos.getY(), time); | |||||
| } | |||||
| } | |||||
| void ComponentPeer::handleMouseDown (const Point<int>& position, const int64 time) | |||||
| { | |||||
| Desktop::getInstance().incrementMouseClickCounter(); | |||||
| updateCurrentModifiers(); | |||||
| if (ModifierKeys::getCurrentModifiers().getNumMouseButtonsDown() == 1) | |||||
| { | |||||
| Component::componentUnderMouse = component->getComponentAt (position); | |||||
| if (Component::componentUnderMouse != 0) | |||||
| { | |||||
| const Point<int> relPos (component->relativePositionToOtherComponent (Component::componentUnderMouse, position)); | |||||
| Component::componentUnderMouse->internalMouseDown (relPos.getX(), relPos.getY(), time); | |||||
| } | |||||
| } | |||||
| } | |||||
| void ComponentPeer::handleMouseDrag (const Point<int>& position, const int64 time) | |||||
| { | |||||
| updateCurrentModifiers(); | |||||
| if (Component::componentUnderMouse != 0) | |||||
| { | |||||
| const Point<int> relPos (component->relativePositionToOtherComponent (Component::componentUnderMouse, position)); | |||||
| Component::componentUnderMouse->internalMouseDrag (relPos.getX(), relPos.getY(), time); | |||||
| } | |||||
| } | |||||
| void ComponentPeer::handleMouseUp (const int oldModifiers, const Point<int>& position, const int64 time) | |||||
| { | |||||
| updateCurrentModifiers(); | |||||
| if (ModifierKeys (oldModifiers).getNumMouseButtonsDown() == 1) | |||||
| { | |||||
| const ComponentDeletionWatcher deletionChecker (component); | |||||
| Component* c = component->getComponentAt (position); | |||||
| if (c != Component::componentUnderMouse) | |||||
| { | |||||
| if (Component::componentUnderMouse != 0) | |||||
| { | |||||
| const Point<int> relPos (component->relativePositionToOtherComponent (Component::componentUnderMouse, position)); | |||||
| Component::componentUnderMouse->internalMouseUp (oldModifiers, relPos.getX(), relPos.getY(), time); | |||||
| if (Component::componentUnderMouse != 0) | |||||
| Component::componentUnderMouse->internalMouseExit (relPos.getX(), relPos.getY(), time); | |||||
| if (deletionChecker.hasBeenDeleted()) | |||||
| return; | |||||
| c = component->getComponentAt (position); | |||||
| } | |||||
| Component::componentUnderMouse = c; | |||||
| if (Component::componentUnderMouse != 0) | |||||
| { | |||||
| const Point<int> relPos (component->relativePositionToOtherComponent (Component::componentUnderMouse, position)); | |||||
| Component::componentUnderMouse->internalMouseEnter (relPos.getX(), relPos.getY(), time); | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| if (Component::componentUnderMouse != 0) | |||||
| { | |||||
| const Point<int> relPos (component->relativePositionToOtherComponent (Component::componentUnderMouse, position)); | |||||
| Component::componentUnderMouse->internalMouseUp (oldModifiers, relPos.getX(), relPos.getY(), time); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| void ComponentPeer::handleMouseExit (const Point<int>& position, const int64 time) | |||||
| { | |||||
| jassert (component->isValidComponent()); | |||||
| updateCurrentModifiers(); | |||||
| if (Component::componentUnderMouse != 0) | |||||
| { | |||||
| const Point<int> relPos (component->relativePositionToOtherComponent (Component::componentUnderMouse, position)); | |||||
| Component::componentUnderMouse->internalMouseExit (relPos.getX(), relPos.getY(), time); | |||||
| Component::componentUnderMouse = 0; | |||||
| } | |||||
| } | |||||
| void ComponentPeer::handleMouseWheel (const int amountX, const int amountY, const int64 time) | |||||
| { | |||||
| updateCurrentModifiers(); | |||||
| if (Component::componentUnderMouse != 0) | |||||
| Component::componentUnderMouse->internalMouseWheel (amountX, amountY, time); | |||||
| } | |||||
| void ComponentPeer::sendFakeMouseMove() throw() | |||||
| { | |||||
| if ((! fakeMouseMessageSent) | |||||
| && component->flags.hasHeavyweightPeerFlag | |||||
| && ! ModifierKeys::getCurrentModifiers().isAnyMouseButtonDown()) | |||||
| { | |||||
| if (! isMinimised()) | |||||
| component->bounds_ = getBounds(); | |||||
| const Point<int> pos (component->getMouseXYRelative()); | |||||
| if (((unsigned int) pos.getX()) < (unsigned int) component->getWidth() | |||||
| && ((unsigned int) pos.getY()) < (unsigned int) component->getHeight() | |||||
| && contains (pos.getX(), pos.getY(), false)) | |||||
| { | |||||
| postMessage (new Message (fakeMouseMoveMessage, pos.getX(), pos.getY(), 0)); | |||||
| } | |||||
| fakeMouseMessageSent = true; | |||||
| } | |||||
| } | |||||
| void ComponentPeer::handleMessage (const Message& message) | |||||
| { | |||||
| if (message.intParameter1 == fakeMouseMoveMessage) | |||||
| { | |||||
| if (! ModifierKeys::getCurrentModifiers().isAnyMouseButtonDown()) | |||||
| handleMouseMove (Point<int> (message.intParameter2, message.intParameter3), | |||||
| Time::currentTimeMillis()); | |||||
| } | |||||
| Desktop::getInstance().getMainMouseSource().handleWheel (this, positionWithinPeer, time, x, y); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -48,7 +48,7 @@ class ComponentDeletionWatcher; | |||||
| @see Component::createNewPeer | @see Component::createNewPeer | ||||
| */ | */ | ||||
| class JUCE_API ComponentPeer : public MessageListener | |||||
| class JUCE_API ComponentPeer | |||||
| { | { | ||||
| public: | public: | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -197,7 +197,7 @@ public: | |||||
| is false, then this returns false if the point is actually inside a child of this | is false, then this returns false if the point is actually inside a child of this | ||||
| window. | window. | ||||
| */ | */ | ||||
| virtual bool contains (int x, int y, bool trueIfInAChildWindow) const = 0; | |||||
| virtual bool contains (const Point<int>& position, bool trueIfInAChildWindow) const = 0; | |||||
| /** Returns the size of the window frame that's around this window. | /** Returns the size of the window frame that's around this window. | ||||
| @@ -295,16 +295,8 @@ public: | |||||
| virtual void performAnyPendingRepaintsNow() = 0; | virtual void performAnyPendingRepaintsNow() = 0; | ||||
| //============================================================================== | //============================================================================== | ||||
| void handleMouseEnter (const Point<int>& position, const int64 time); | |||||
| void handleMouseMove (const Point<int>& position, const int64 time); | |||||
| void handleMouseDown (const Point<int>& position, const int64 time); | |||||
| void handleMouseDrag (const Point<int>& position, const int64 time); | |||||
| void handleMouseUp (const int oldModifiers, const Point<int>& position, const int64 time); | |||||
| void handleMouseExit (const Point<int>& position, const int64 time); | |||||
| void handleMouseWheel (const int amountX, const int amountY, const int64 time); | |||||
| /** Causes a mouse-move callback to be made asynchronously. */ | |||||
| void sendFakeMouseMove() throw(); | |||||
| void handleMouseEvent (const Point<int>& positionWithinPeer, const ModifierKeys& newMods, const int64 time); | |||||
| void handleMouseWheel (const Point<int>& positionWithinPeer, const int64 time, float x, float y); | |||||
| void handleUserClosingWindow(); | void handleUserClosingWindow(); | ||||
| @@ -373,9 +365,6 @@ protected: | |||||
| static void updateCurrentModifiers() throw(); | static void updateCurrentModifiers() throw(); | ||||
| /** @internal */ | |||||
| void handleMessage (const Message& message); | |||||
| private: | private: | ||||
| //============================================================================== | //============================================================================== | ||||
| Component* lastFocusedComponent; | Component* lastFocusedComponent; | ||||
| @@ -230,7 +230,7 @@ public: | |||||
| start = roundToInt ((y - yTerm) * grad); | start = roundToInt ((y - yTerm) * grad); | ||||
| } | } | ||||
| forcedinline const PixelARGB getPixel (const int x) const throw() | |||||
| inline const PixelARGB getPixel (const int x) const throw() | |||||
| { | { | ||||
| return vertical ? linePix | return vertical ? linePix | ||||
| : lookupTable [jlimit (0, numEntries, (x * scale - start) >> (int) numScaleBits)]; | : lookupTable [jlimit (0, numEntries, (x * scale - start) >> (int) numScaleBits)]; | ||||
| @@ -274,7 +274,7 @@ public: | |||||
| dy *= dy; | dy *= dy; | ||||
| } | } | ||||
| forcedinline const PixelARGB getPixel (const int px) const throw() | |||||
| inline const PixelARGB getPixel (const int px) const throw() | |||||
| { | { | ||||
| double x = px - gx1; | double x = px - gx1; | ||||
| x *= x; | x *= x; | ||||
| @@ -312,7 +312,7 @@ public: | |||||
| lineYM11 = inverseTransform.mat11 * y + inverseTransform.mat12 - gy1; | lineYM11 = inverseTransform.mat11 * y + inverseTransform.mat12 - gy1; | ||||
| } | } | ||||
| forcedinline const PixelARGB getPixel (const int px) const throw() | |||||
| inline const PixelARGB getPixel (const int px) const throw() | |||||
| { | { | ||||
| double x = px; | double x = px; | ||||
| const double y = tM10 * x + lineYM11; | const double y = tM10 * x + lineYM11; | ||||
| @@ -254,23 +254,23 @@ int OutputStream::writeFromInputStream (InputStream& source, int numBytesToWrite | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const int number) | |||||
| OutputStream& operator<< (OutputStream& stream, const int number) | |||||
| { | { | ||||
| return stream << String (number); | return stream << String (number); | ||||
| } | } | ||||
| OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const double number) | |||||
| OutputStream& operator<< (OutputStream& stream, const double number) | |||||
| { | { | ||||
| return stream << String (number); | return stream << String (number); | ||||
| } | } | ||||
| OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const char character) | |||||
| OutputStream& operator<< (OutputStream& stream, const char character) | |||||
| { | { | ||||
| stream.writeByte (character); | stream.writeByte (character); | ||||
| return stream; | return stream; | ||||
| } | } | ||||
| OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const char* const text) | |||||
| OutputStream& operator<< (OutputStream& stream, const char* const text) | |||||
| { | { | ||||
| stream.write (text, (int) strlen (text)); | stream.write (text, (int) strlen (text)); | ||||
| return stream; | return stream; | ||||
| @@ -207,16 +207,16 @@ public: | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Writes a number to a stream as 8-bit characters in the default system encoding. */ | /** Writes a number to a stream as 8-bit characters in the default system encoding. */ | ||||
| OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const int number); | |||||
| OutputStream& operator<< (OutputStream& stream, const int number); | |||||
| /** Writes a number to a stream as 8-bit characters in the default system encoding. */ | /** Writes a number to a stream as 8-bit characters in the default system encoding. */ | ||||
| OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const double number); | |||||
| OutputStream& operator<< (OutputStream& stream, const double number); | |||||
| /** Writes a character to a stream. */ | /** Writes a character to a stream. */ | ||||
| OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const char character); | |||||
| OutputStream& operator<< (OutputStream& stream, const char character); | |||||
| /** Writes a null-terminated text string to a stream. */ | /** Writes a null-terminated text string to a stream. */ | ||||
| OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const char* const text); | |||||
| OutputStream& operator<< (OutputStream& stream, const char* const text); | |||||
| @@ -59,6 +59,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_MouseEvent.h" | |||||
| #include "../gui/components/keyboard/juce_KeyPressMappingSet.h" | #include "../gui/components/keyboard/juce_KeyPressMappingSet.h" | ||||
| #include "../gui/components/special/juce_NSViewComponent.h" | #include "../gui/components/special/juce_NSViewComponent.h" | ||||
| #include "../gui/components/layout/juce_ComponentMovementWatcher.h" | #include "../gui/components/layout/juce_ComponentMovementWatcher.h" | ||||
| @@ -120,33 +120,6 @@ enum MouseButtons | |||||
| WheelDown = 5 | WheelDown = 5 | ||||
| }; | }; | ||||
| static const Point<int> getMousePos (int& mouseMods) throw() | |||||
| { | |||||
| Window root, child; | |||||
| int x, y, winx, winy; | |||||
| unsigned int mask; | |||||
| mouseMods = 0; | |||||
| ScopedXLock xlock; | |||||
| if (XQueryPointer (display, | |||||
| RootWindow (display, DefaultScreen (display)), | |||||
| &root, &child, | |||||
| &x, &y, &winx, &winy, &mask) == False) | |||||
| { | |||||
| // Pointer not on the default screen | |||||
| x = y = -1; | |||||
| } | |||||
| else | |||||
| { | |||||
| if ((mask & Button1Mask) != 0) mouseMods |= ModifierKeys::leftButtonModifier; | |||||
| if ((mask & Button2Mask) != 0) mouseMods |= ModifierKeys::middleButtonModifier; | |||||
| if ((mask & Button3Mask) != 0) mouseMods |= ModifierKeys::rightButtonModifier; | |||||
| } | |||||
| return Point<int> (x, y); | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| static int AltMask = 0; | static int AltMask = 0; | ||||
| static int NumLockMask = 0; | static int NumLockMask = 0; | ||||
| @@ -200,124 +173,6 @@ bool KeyPress::isKeyCurrentlyDown (const int keyCode) throw() | |||||
| return keyDown (XKeysymToKeycode (display, keysym)); | return keyDown (XKeysymToKeycode (display, keysym)); | ||||
| } | } | ||||
| //============================================================================== | |||||
| // Alt and Num lock are not defined by standard X | |||||
| // modifier constants: check what they're mapped to | |||||
| static void getModifierMapping() throw() | |||||
| { | |||||
| ScopedXLock xlock; | |||||
| const int altLeftCode = XKeysymToKeycode (display, XK_Alt_L); | |||||
| const int numLockCode = XKeysymToKeycode (display, XK_Num_Lock); | |||||
| AltMask = 0; | |||||
| NumLockMask = 0; | |||||
| XModifierKeymap* mapping = XGetModifierMapping (display); | |||||
| if (mapping) | |||||
| { | |||||
| for (int i = 0; i < 8; i++) | |||||
| { | |||||
| if (mapping->modifiermap [i << 1] == altLeftCode) | |||||
| AltMask = 1 << i; | |||||
| else if (mapping->modifiermap [i << 1] == numLockCode) | |||||
| NumLockMask = 1 << i; | |||||
| } | |||||
| XFreeModifiermap (mapping); | |||||
| } | |||||
| } | |||||
| static int currentModifiers = 0; | |||||
| void ModifierKeys::updateCurrentModifiers() throw() | |||||
| { | |||||
| currentModifierFlags = currentModifiers; | |||||
| } | |||||
| const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() throw() | |||||
| { | |||||
| int mouseMods; | |||||
| getMousePos (mouseMods); | |||||
| currentModifiers &= ~ModifierKeys::allMouseButtonModifiers; | |||||
| currentModifiers |= mouseMods; | |||||
| return ModifierKeys (currentModifiers); | |||||
| } | |||||
| static void updateKeyModifiers (const int status) throw() | |||||
| { | |||||
| currentModifiers &= ~(ModifierKeys::shiftModifier | |||||
| | ModifierKeys::ctrlModifier | |||||
| | ModifierKeys::altModifier); | |||||
| if (status & ShiftMask) | |||||
| currentModifiers |= ModifierKeys::shiftModifier; | |||||
| if (status & ControlMask) | |||||
| currentModifiers |= ModifierKeys::ctrlModifier; | |||||
| if (status & AltMask) | |||||
| currentModifiers |= ModifierKeys::altModifier; | |||||
| numLock = ((status & NumLockMask) != 0); | |||||
| capsLock = ((status & LockMask) != 0); | |||||
| } | |||||
| static bool updateKeyModifiersFromSym (KeySym sym, const bool press) throw() | |||||
| { | |||||
| int modifier = 0; | |||||
| bool isModifier = true; | |||||
| switch (sym) | |||||
| { | |||||
| case XK_Shift_L: | |||||
| case XK_Shift_R: | |||||
| modifier = ModifierKeys::shiftModifier; | |||||
| break; | |||||
| case XK_Control_L: | |||||
| case XK_Control_R: | |||||
| modifier = ModifierKeys::ctrlModifier; | |||||
| break; | |||||
| case XK_Alt_L: | |||||
| case XK_Alt_R: | |||||
| modifier = ModifierKeys::altModifier; | |||||
| break; | |||||
| case XK_Num_Lock: | |||||
| if (press) | |||||
| numLock = ! numLock; | |||||
| break; | |||||
| case XK_Caps_Lock: | |||||
| if (press) | |||||
| capsLock = ! capsLock; | |||||
| break; | |||||
| case XK_Scroll_Lock: | |||||
| break; | |||||
| default: | |||||
| isModifier = false; | |||||
| break; | |||||
| } | |||||
| if (modifier != 0) | |||||
| { | |||||
| if (press) | |||||
| currentModifiers |= modifier; | |||||
| else | |||||
| currentModifiers &= ~modifier; | |||||
| } | |||||
| return isModifier; | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| #if JUCE_USE_XSHM | #if JUCE_USE_XSHM | ||||
| static bool isShmAvailable() throw() | static bool isShmAvailable() throw() | ||||
| @@ -605,7 +460,6 @@ public: | |||||
| wh (0), | wh (0), | ||||
| taskbarImage (0), | taskbarImage (0), | ||||
| fullScreen (false), | fullScreen (false), | ||||
| entered (false), | |||||
| mapped (false) | mapped (false) | ||||
| { | { | ||||
| // it's dangerous to create a window on a thread other than the message thread.. | // it's dangerous to create a window on a thread other than the message thread.. | ||||
| @@ -644,7 +498,7 @@ public: | |||||
| ScopedXLock xlock; | ScopedXLock xlock; | ||||
| if (! XFindContext (display, (XID) windowHandle, improbableNumber, &peer)) | if (! XFindContext (display, (XID) windowHandle, improbableNumber, &peer)) | ||||
| { | { | ||||
| if (peer != 0 && ! ((LinuxComponentPeer*) peer)->isValidMessageListener()) | |||||
| if (peer != 0 && ! ComponentPeer::isValidPeer ((LinuxComponentPeer*) peer)) | |||||
| peer = 0; | peer = 0; | ||||
| } | } | ||||
| @@ -854,9 +708,10 @@ public: | |||||
| return result; | return result; | ||||
| } | } | ||||
| bool contains (int x, int y, bool trueIfInAChildWindow) const | |||||
| bool contains (const Point<int>& position, bool trueIfInAChildWindow) const | |||||
| { | { | ||||
| jassert (x >= 0 && y >= 0 && x < ww && y < wh); // should only be called for points that are actually inside the bounds | |||||
| int x = position.getX(); | |||||
| int y = position.getY(); | |||||
| if (((unsigned int) x) >= (unsigned int) ww | if (((unsigned int) x) >= (unsigned int) ww | ||||
| || ((unsigned int) y) >= (unsigned int) wh) | || ((unsigned int) y) >= (unsigned int) wh) | ||||
| @@ -1166,10 +1021,9 @@ public: | |||||
| int keyCode = (int) unicodeChar; | int keyCode = (int) unicodeChar; | ||||
| if (keyCode < 0x20) | if (keyCode < 0x20) | ||||
| keyCode = XKeycodeToKeysym (display, keyEvent->keycode, | |||||
| (currentModifiers & ModifierKeys::shiftModifier) != 0 ? 1 : 0); | |||||
| keyCode = XKeycodeToKeysym (display, keyEvent->keycode, currentModifiers.isShiftDown() ? 1 : 0); | |||||
| const int oldMods = currentModifiers; | |||||
| const ModifierKeys oldMods (currentModifiers); | |||||
| bool keyPressed = false; | bool keyPressed = false; | ||||
| const bool keyDownChange = (sym != NoSymbol) && ! updateKeyModifiersFromSym (sym, true); | const bool keyDownChange = (sym != NoSymbol) && ! updateKeyModifiersFromSym (sym, true); | ||||
| @@ -1267,7 +1121,7 @@ public: | |||||
| ScopedXLock xlock; | ScopedXLock xlock; | ||||
| KeySym sym = XKeycodeToKeysym (display, keyEvent->keycode, 0); | KeySym sym = XKeycodeToKeysym (display, keyEvent->keycode, 0); | ||||
| const int oldMods = currentModifiers; | |||||
| const ModifierKeys oldMods (currentModifiers); | |||||
| const bool keyDownChange = (sym != NoSymbol) && ! updateKeyModifiersFromSym (sym, false); | const bool keyDownChange = (sym != NoSymbol) && ! updateKeyModifiersFromSym (sym, false); | ||||
| if (oldMods != currentModifiers) | if (oldMods != currentModifiers) | ||||
| @@ -1282,48 +1136,37 @@ public: | |||||
| case ButtonPress: | case ButtonPress: | ||||
| { | { | ||||
| const XButtonPressedEvent* const buttonPressEvent = (const XButtonPressedEvent*) &event->xbutton; | const XButtonPressedEvent* const buttonPressEvent = (const XButtonPressedEvent*) &event->xbutton; | ||||
| updateKeyModifiers (buttonPressEvent->state); | |||||
| bool buttonMsg = false; | bool buttonMsg = false; | ||||
| bool wheelUpMsg = false; | |||||
| bool wheelDownMsg = false; | |||||
| const int map = pointerMap [buttonPressEvent->button - Button1]; | const int map = pointerMap [buttonPressEvent->button - Button1]; | ||||
| if (map == WheelUp || map == WheelDown) | |||||
| { | |||||
| handleMouseWheel (Point<int> (buttonPressEvent->x, buttonPressEvent->y), | |||||
| getEventTime (buttonPressEvent->time), 0, map == WheelDown ? -84.0f : 84.0f); | |||||
| } | |||||
| if (map == LeftButton) | if (map == LeftButton) | ||||
| { | { | ||||
| currentModifiers |= ModifierKeys::leftButtonModifier; | |||||
| currentModifiers = currentModifiers.withFlags (ModifierKeys::leftButtonModifier); | |||||
| buttonMsg = true; | buttonMsg = true; | ||||
| } | } | ||||
| else if (map == RightButton) | else if (map == RightButton) | ||||
| { | { | ||||
| currentModifiers |= ModifierKeys::rightButtonModifier; | |||||
| currentModifiers = currentModifiers.withFlags (ModifierKeys::rightButtonModifier); | |||||
| buttonMsg = true; | buttonMsg = true; | ||||
| } | } | ||||
| else if (map == MiddleButton) | else if (map == MiddleButton) | ||||
| { | { | ||||
| currentModifiers |= ModifierKeys::middleButtonModifier; | |||||
| currentModifiers = currentModifiers.withFlags (ModifierKeys::middleButtonModifier); | |||||
| buttonMsg = true; | buttonMsg = true; | ||||
| } | } | ||||
| else if (map == WheelUp) | |||||
| { | |||||
| wheelUpMsg = true; | |||||
| } | |||||
| else if (map == WheelDown) | |||||
| { | |||||
| wheelDownMsg = true; | |||||
| } | |||||
| updateKeyModifiers (buttonPressEvent->state); | |||||
| if (buttonMsg) | if (buttonMsg) | ||||
| { | { | ||||
| toFront (true); | toFront (true); | ||||
| handleMouseDown (Point<int> (buttonPressEvent->x, buttonPressEvent->y), | |||||
| getEventTime (buttonPressEvent->time)); | |||||
| } | |||||
| else if (wheelUpMsg || wheelDownMsg) | |||||
| { | |||||
| handleMouseWheel (0, wheelDownMsg ? -84 : 84, | |||||
| handleMouseEvent (Point<int> (buttonPressEvent->x, buttonPressEvent->y), currentModifiers, | |||||
| getEventTime (buttonPressEvent->time)); | getEventTime (buttonPressEvent->time)); | ||||
| } | } | ||||
| @@ -1334,22 +1177,19 @@ public: | |||||
| case ButtonRelease: | case ButtonRelease: | ||||
| { | { | ||||
| const XButtonReleasedEvent* const buttonRelEvent = (const XButtonReleasedEvent*) &event->xbutton; | const XButtonReleasedEvent* const buttonRelEvent = (const XButtonReleasedEvent*) &event->xbutton; | ||||
| updateKeyModifiers (buttonRelEvent->state); | |||||
| const int oldModifiers = currentModifiers; | |||||
| const int map = pointerMap [buttonRelEvent->button - Button1]; | const int map = pointerMap [buttonRelEvent->button - Button1]; | ||||
| if (map == LeftButton) | if (map == LeftButton) | ||||
| currentModifiers &= ~ModifierKeys::leftButtonModifier; | |||||
| currentModifiers = currentModifiers.withoutFlags (ModifierKeys::leftButtonModifier); | |||||
| else if (map == RightButton) | else if (map == RightButton) | ||||
| currentModifiers &= ~ModifierKeys::rightButtonModifier; | |||||
| currentModifiers = currentModifiers.withoutFlags (ModifierKeys::rightButtonModifier); | |||||
| else if (map == MiddleButton) | else if (map == MiddleButton) | ||||
| currentModifiers &= ~ModifierKeys::middleButtonModifier; | |||||
| updateKeyModifiers (buttonRelEvent->state); | |||||
| currentModifiers = currentModifiers.withoutFlags (ModifierKeys::middleButtonModifier); | |||||
| handleMouseUp (oldModifiers, | |||||
| Point<int> (buttonRelEvent->x, buttonRelEvent->y), | |||||
| getEventTime (buttonRelEvent->time)); | |||||
| handleMouseEvent (Point<int> (buttonRelEvent->x, buttonRelEvent->y), currentModifiers, | |||||
| getEventTime (buttonRelEvent->time)); | |||||
| clearLastMousePos(); | clearLastMousePos(); | ||||
| break; | break; | ||||
| @@ -1358,10 +1198,9 @@ public: | |||||
| case MotionNotify: | case MotionNotify: | ||||
| { | { | ||||
| const XPointerMovedEvent* const movedEvent = (const XPointerMovedEvent*) &event->xmotion; | const XPointerMovedEvent* const movedEvent = (const XPointerMovedEvent*) &event->xmotion; | ||||
| updateKeyModifiers (movedEvent->state); | updateKeyModifiers (movedEvent->state); | ||||
| Point<int> mousePos (Desktop::getMousePosition()); | |||||
| const Point<int> mousePos (Desktop::getMousePosition()); | |||||
| if (lastMousePos != mousePos) | if (lastMousePos != mousePos) | ||||
| { | { | ||||
| @@ -1370,37 +1209,28 @@ public: | |||||
| if (parentWindow != 0 && (styleFlags & windowHasTitleBar) == 0) | if (parentWindow != 0 && (styleFlags & windowHasTitleBar) == 0) | ||||
| { | { | ||||
| Window wRoot = 0, wParent = 0; | Window wRoot = 0, wParent = 0; | ||||
| Window* wChild = 0; | |||||
| unsigned int numChildren; | |||||
| { | { | ||||
| ScopedXLock xlock; | ScopedXLock xlock; | ||||
| unsigned int numChildren; | |||||
| Window* wChild = 0; | |||||
| XQueryTree (display, windowH, &wRoot, &wParent, &wChild, &numChildren); | XQueryTree (display, windowH, &wRoot, &wParent, &wChild, &numChildren); | ||||
| } | } | ||||
| if (wParent != 0 | if (wParent != 0 | ||||
| && wParent != windowH | |||||
| && wParent != wRoot) | |||||
| && wParent != windowH | |||||
| && wParent != wRoot) | |||||
| { | { | ||||
| parentWindow = wParent; | parentWindow = wParent; | ||||
| updateBounds(); | updateBounds(); | ||||
| mousePos -= getScreenPosition(); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| parentWindow = 0; | parentWindow = 0; | ||||
| mousePos -= getScreenPosition(); | |||||
| } | } | ||||
| } | } | ||||
| else | |||||
| { | |||||
| mousePos -= getScreenPosition(); | |||||
| } | |||||
| if ((currentModifiers & ModifierKeys::allMouseButtonModifiers) == 0) | |||||
| handleMouseMove (mousePos, getEventTime (movedEvent->time)); | |||||
| else | |||||
| handleMouseDrag (mousePos, getEventTime (movedEvent->time)); | |||||
| handleMouseEvent (mousePos - getScreenPosition(), currentModifiers, getEventTime (movedEvent->time)); | |||||
| } | } | ||||
| break; | break; | ||||
| @@ -1411,14 +1241,10 @@ public: | |||||
| clearLastMousePos(); | clearLastMousePos(); | ||||
| const XEnterWindowEvent* const enterEvent = (const XEnterWindowEvent*) &event->xcrossing; | const XEnterWindowEvent* const enterEvent = (const XEnterWindowEvent*) &event->xcrossing; | ||||
| if ((currentModifiers & ModifierKeys::allMouseButtonModifiers) == 0 | |||||
| && ! entered) | |||||
| if (! currentModifiers.isAnyMouseButtonDown()) | |||||
| { | { | ||||
| updateKeyModifiers (enterEvent->state); | updateKeyModifiers (enterEvent->state); | ||||
| handleMouseEnter (Point<int> (enterEvent->x, enterEvent->y), getEventTime (enterEvent->time)); | |||||
| entered = true; | |||||
| handleMouseEvent (Point<int> (enterEvent->x, enterEvent->y), currentModifiers, getEventTime (enterEvent->time)); | |||||
| } | } | ||||
| break; | break; | ||||
| @@ -1431,15 +1257,11 @@ public: | |||||
| // Suppress the normal leave if we've got a pointer grab, or if | // Suppress the normal leave if we've got a pointer grab, or if | ||||
| // it's a bogus one caused by clicking a mouse button when running | // it's a bogus one caused by clicking a mouse button when running | ||||
| // in a Window manager | // in a Window manager | ||||
| if (((currentModifiers & ModifierKeys::allMouseButtonModifiers) == 0 | |||||
| && leaveEvent->mode == NotifyNormal) | |||||
| || leaveEvent->mode == NotifyUngrab) | |||||
| if (((! currentModifiers.isAnyMouseButtonDown()) && leaveEvent->mode == NotifyNormal) | |||||
| || leaveEvent->mode == NotifyUngrab) | |||||
| { | { | ||||
| updateKeyModifiers (leaveEvent->state); | updateKeyModifiers (leaveEvent->state); | ||||
| handleMouseExit (Point<int> (leaveEvent->x, leaveEvent->y), getEventTime (leaveEvent->time)); | |||||
| entered = false; | |||||
| handleMouseEvent (Point<int> (leaveEvent->x, leaveEvent->y), currentModifiers, getEventTime (leaveEvent->time)); | |||||
| } | } | ||||
| break; | break; | ||||
| @@ -1570,7 +1392,7 @@ public: | |||||
| // Deal with modifier/keyboard mapping | // Deal with modifier/keyboard mapping | ||||
| ScopedXLock xlock; | ScopedXLock xlock; | ||||
| XRefreshKeyboardMapping (mappingEvent); | XRefreshKeyboardMapping (mappingEvent); | ||||
| getModifierMapping(); | |||||
| updateModifierMappings(); | |||||
| } | } | ||||
| break; | break; | ||||
| @@ -1726,6 +1548,8 @@ public: | |||||
| bool dontRepaint; | bool dontRepaint; | ||||
| static ModifierKeys currentModifiers; | |||||
| private: | private: | ||||
| //============================================================================== | //============================================================================== | ||||
| class LinuxRepaintManager : public Timer | class LinuxRepaintManager : public Timer | ||||
| @@ -1870,7 +1694,7 @@ private: | |||||
| Window windowH, parentWindow; | Window windowH, parentWindow; | ||||
| int wx, wy, ww, wh; | int wx, wy, ww, wh; | ||||
| Image* taskbarImage; | Image* taskbarImage; | ||||
| bool fullScreen, entered, mapped, depthIs16Bit; | |||||
| bool fullScreen, mapped, depthIs16Bit; | |||||
| BorderSize windowBorder; | BorderSize windowBorder; | ||||
| struct MotifWmHints | struct MotifWmHints | ||||
| @@ -1882,6 +1706,100 @@ private: | |||||
| unsigned long status; | unsigned long status; | ||||
| }; | }; | ||||
| static void updateKeyModifiers (const int status) throw() | |||||
| { | |||||
| int keyMods = 0; | |||||
| if (status & ShiftMask) keyMods |= ModifierKeys::shiftModifier; | |||||
| if (status & ControlMask) keyMods |= ModifierKeys::ctrlModifier; | |||||
| if (status & AltMask) keyMods |= ModifierKeys::altModifier; | |||||
| currentModifiers = currentModifiers.withOnlyMouseButtons().withFlags (keyMods); | |||||
| numLock = ((status & NumLockMask) != 0); | |||||
| capsLock = ((status & LockMask) != 0); | |||||
| } | |||||
| static bool updateKeyModifiersFromSym (KeySym sym, const bool press) throw() | |||||
| { | |||||
| int modifier = 0; | |||||
| bool isModifier = true; | |||||
| switch (sym) | |||||
| { | |||||
| case XK_Shift_L: | |||||
| case XK_Shift_R: | |||||
| modifier = ModifierKeys::shiftModifier; | |||||
| break; | |||||
| case XK_Control_L: | |||||
| case XK_Control_R: | |||||
| modifier = ModifierKeys::ctrlModifier; | |||||
| break; | |||||
| case XK_Alt_L: | |||||
| case XK_Alt_R: | |||||
| modifier = ModifierKeys::altModifier; | |||||
| break; | |||||
| case XK_Num_Lock: | |||||
| if (press) | |||||
| numLock = ! numLock; | |||||
| break; | |||||
| case XK_Caps_Lock: | |||||
| if (press) | |||||
| capsLock = ! capsLock; | |||||
| break; | |||||
| case XK_Scroll_Lock: | |||||
| break; | |||||
| default: | |||||
| isModifier = false; | |||||
| break; | |||||
| } | |||||
| if (modifier != 0) | |||||
| { | |||||
| if (press) | |||||
| currentModifiers = currentModifiers.withFlags (modifier); | |||||
| else | |||||
| currentModifiers = currentModifiers.withoutFlags (modifier); | |||||
| } | |||||
| return isModifier; | |||||
| } | |||||
| // Alt and Num lock are not defined by standard X | |||||
| // modifier constants: check what they're mapped to | |||||
| static void updateModifierMappings() throw() | |||||
| { | |||||
| ScopedXLock xlock; | |||||
| const int altLeftCode = XKeysymToKeycode (display, XK_Alt_L); | |||||
| const int numLockCode = XKeysymToKeycode (display, XK_Num_Lock); | |||||
| AltMask = 0; | |||||
| NumLockMask = 0; | |||||
| XModifierKeymap* mapping = XGetModifierMapping (display); | |||||
| if (mapping) | |||||
| { | |||||
| for (int i = 0; i < 8; i++) | |||||
| { | |||||
| if (mapping->modifiermap [i << 1] == altLeftCode) | |||||
| AltMask = 1 << i; | |||||
| else if (mapping->modifiermap [i << 1] == numLockCode) | |||||
| NumLockMask = 1 << i; | |||||
| } | |||||
| XFreeModifiermap (mapping); | |||||
| } | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| void removeWindowDecorations (Window wndH) | void removeWindowDecorations (Window wndH) | ||||
| { | { | ||||
| @@ -2195,7 +2113,7 @@ private: | |||||
| } | } | ||||
| } | } | ||||
| getModifierMapping(); | |||||
| updateModifierMappings(); | |||||
| } | } | ||||
| windowH = wndH; | windowH = wndH; | ||||
| @@ -2220,7 +2138,7 @@ private: | |||||
| {} | {} | ||||
| } | } | ||||
| static int64 getEventTime (::Time t) throw() | |||||
| static int64 getEventTime (::Time t) | |||||
| { | { | ||||
| static int64 eventTimeOffset = 0x12345678; | static int64 eventTimeOffset = 0x12345678; | ||||
| const int64 thisMessageTime = t; | const int64 thisMessageTime = t; | ||||
| @@ -2566,9 +2484,37 @@ private: | |||||
| } | } | ||||
| }; | }; | ||||
| ModifierKeys LinuxComponentPeer::currentModifiers; | |||||
| int LinuxComponentPeer::pointerMap[5]; | int LinuxComponentPeer::pointerMap[5]; | ||||
| Point<int> LinuxComponentPeer::lastMousePos; | Point<int> LinuxComponentPeer::lastMousePos; | ||||
| //============================================================================== | |||||
| void ModifierKeys::updateCurrentModifiers() throw() | |||||
| { | |||||
| currentModifiers = LinuxComponentPeer::currentModifiers; | |||||
| } | |||||
| const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() throw() | |||||
| { | |||||
| Window root, child; | |||||
| int x, y, winx, winy; | |||||
| unsigned int mask; | |||||
| int mouseMods = 0; | |||||
| ScopedXLock xlock; | |||||
| if (XQueryPointer (display, RootWindow (display, DefaultScreen (display)), | |||||
| &root, &child, &x, &y, &winx, &winy, &mask) != False) | |||||
| { | |||||
| if ((mask & Button1Mask) != 0) mouseMods |= ModifierKeys::leftButtonModifier; | |||||
| if ((mask & Button2Mask) != 0) mouseMods |= ModifierKeys::middleButtonModifier; | |||||
| if ((mask & Button3Mask) != 0) mouseMods |= ModifierKeys::rightButtonModifier; | |||||
| } | |||||
| LinuxComponentPeer::currentModifiers = LinuxComponentPeer::currentModifiers.withoutMouseButtons().withFlags (mouseMods); | |||||
| return LinuxComponentPeer::currentModifiers; | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| void juce_setKioskComponent (Component* kioskModeComponent, bool enableOrDisable, bool allowMenusAndBars) | void juce_setKioskComponent (Component* kioskModeComponent, bool enableOrDisable, bool allowMenusAndBars) | ||||
| @@ -2721,8 +2667,22 @@ bool Desktop::canUseSemiTransparentWindows() throw() | |||||
| const Point<int> Desktop::getMousePosition() | const Point<int> Desktop::getMousePosition() | ||||
| { | { | ||||
| int mouseMods; | |||||
| return getMousePos (mouseMods); | |||||
| Window root, child; | |||||
| int x, y, winx, winy; | |||||
| unsigned int mask; | |||||
| ScopedXLock xlock; | |||||
| if (XQueryPointer (display, | |||||
| RootWindow (display, DefaultScreen (display)), | |||||
| &root, &child, | |||||
| &x, &y, &winx, &winy, &mask) == False) | |||||
| { | |||||
| // Pointer not on the default screen | |||||
| x = y = -1; | |||||
| } | |||||
| return Point<int> (x, y); | |||||
| } | } | ||||
| void Desktop::setMousePosition (const Point<int>& newPosition) | void Desktop::setMousePosition (const Point<int>& newPosition) | ||||
| @@ -101,7 +101,7 @@ public: | |||||
| bool isMinimised() const; | bool isMinimised() const; | ||||
| void setFullScreen (bool shouldBeFullScreen); | void setFullScreen (bool shouldBeFullScreen); | ||||
| bool isFullScreen() const; | bool isFullScreen() const; | ||||
| bool contains (int x, int y, bool trueIfInAChildWindow) const; | |||||
| bool contains (const Point<int>& position, bool trueIfInAChildWindow) const; | |||||
| const BorderSize getFrameSize() const; | const BorderSize getFrameSize() const; | ||||
| bool setAlwaysOnTop (bool alwaysOnTop); | bool setAlwaysOnTop (bool alwaysOnTop); | ||||
| void toFront (bool makeActiveWindow); | void toFront (bool makeActiveWindow); | ||||
| @@ -133,6 +133,7 @@ public: | |||||
| UIWindow* window; | UIWindow* window; | ||||
| JuceUIView* view; | JuceUIView* view; | ||||
| bool isSharedWindow, fullScreen, insideDrawRect; | bool isSharedWindow, fullScreen, insideDrawRect; | ||||
| static ModifierKeys currentModifiers; | |||||
| }; | }; | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -167,23 +168,16 @@ bool KeyPress::isKeyCurrentlyDown (const int keyCode) throw() | |||||
| return false; | return false; | ||||
| } | } | ||||
| static int currentModifiers = 0; | |||||
| ModifierKeys UIViewComponentPeer::currentModifiers; | |||||
| const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() throw() | const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() throw() | ||||
| { | { | ||||
| return ModifierKeys (currentModifiers); | |||||
| return UIViewComponentPeer::currentModifiers; | |||||
| } | } | ||||
| void ModifierKeys::updateCurrentModifiers() throw() | void ModifierKeys::updateCurrentModifiers() throw() | ||||
| { | { | ||||
| currentModifierFlags = currentModifiers; | |||||
| } | |||||
| static int getModifierForButtonNumber (const int num) | |||||
| { | |||||
| return num == 0 ? ModifierKeys::leftButtonModifier | |||||
| : (num == 1 ? ModifierKeys::rightButtonModifier | |||||
| : (num == 2 ? ModifierKeys::middleButtonModifier : 0)); | |||||
| currentModifiers = UIViewComponentPeer::currentModifiers; | |||||
| } | } | ||||
| static int64 getMouseTime (UIEvent* e) | static int64 getMouseTime (UIEvent* e) | ||||
| @@ -208,13 +202,15 @@ JUCE_NAMESPACE::Point<int> juce_lastMousePos; | |||||
| { | { | ||||
| CGPoint p = [[t objectAtIndex: 0] locationInView: self]; | CGPoint p = [[t objectAtIndex: 0] locationInView: self]; | ||||
| const JUCE_NAMESPACE::Point<int> pos ((int) p.x, (int) p.y); | const JUCE_NAMESPACE::Point<int> pos ((int) p.x, (int) p.y); | ||||
| currentModifiers |= getModifierForButtonNumber (0); | |||||
| juce_lastMousePos = pos + owner->getScreenPosition(); | juce_lastMousePos = pos + owner->getScreenPosition(); | ||||
| owner->handleMouseMove (pos, getMouseTime (event)); | |||||
| owner->handleMouseEvent (pos, JUCE_NAMESPACE::UIViewComponentPeer::currentModifiers, getMouseTime (event)); | |||||
| if (owner != 0) | |||||
| owner->handleMouseDown (pos, getMouseTime (event)); | |||||
| JUCE_NAMESPACE::UIViewComponentPeer::currentModifiers | |||||
| = JUCE_NAMESPACE::UIViewComponentPeer::currentModifiers.withoutMouseButtons() | |||||
| .withFlags (JUCE_NAMESPACE::ModifierKeys::leftButtonModifier); | |||||
| owner->handleMouseEvent (pos, JUCE_NAMESPACE::UIViewComponentPeer::currentModifiers, getMouseTime (event)); | |||||
| } | } | ||||
| default: | default: | ||||
| @@ -238,7 +234,7 @@ JUCE_NAMESPACE::Point<int> juce_lastMousePos; | |||||
| const JUCE_NAMESPACE::Point<int> pos ((int) p.x, (int) p.y); | const JUCE_NAMESPACE::Point<int> pos ((int) p.x, (int) p.y); | ||||
| juce_lastMousePos = pos + owner->getScreenPosition(); | juce_lastMousePos = pos + owner->getScreenPosition(); | ||||
| owner->handleMouseDrag (pos, getMouseTime (event)); | |||||
| owner->handleMouseEvent (pos, JUCE_NAMESPACE::UIViewComponentPeer::currentModifiers, getMouseTime (event)); | |||||
| } | } | ||||
| default: | default: | ||||
| @@ -262,9 +258,10 @@ JUCE_NAMESPACE::Point<int> juce_lastMousePos; | |||||
| const JUCE_NAMESPACE::Point<int> pos ((int) p.x, (int) p.y); | const JUCE_NAMESPACE::Point<int> pos ((int) p.x, (int) p.y); | ||||
| juce_lastMousePos = pos + owner->getScreenPosition(); | juce_lastMousePos = pos + owner->getScreenPosition(); | ||||
| const int oldMods = currentModifiers; | |||||
| currentModifiers &= ~getModifierForButtonNumber (0); | |||||
| owner->handleMouseUp (oldMods, pos, getMouseTime (event)); | |||||
| JUCE_NAMESPACE::UIViewComponentPeer::currentModifiers | |||||
| = JUCE_NAMESPACE::UIViewComponentPeer::currentModifiers.withoutMouseButtons(); | |||||
| owner->handleMouseEvent (pos, JUCE_NAMESPACE::UIViewComponentPeer::currentModifiers, getMouseTime (event)); | |||||
| } | } | ||||
| default: | default: | ||||
| @@ -559,15 +556,15 @@ bool UIViewComponentPeer::isFullScreen() const | |||||
| return fullScreen; | return fullScreen; | ||||
| } | } | ||||
| bool UIViewComponentPeer::contains (int x, int y, bool trueIfInAChildWindow) const | |||||
| bool UIViewComponentPeer::contains (const Point<int>& position, bool trueIfInAChildWindow) const | |||||
| { | { | ||||
| if (((unsigned int) x) >= (unsigned int) component->getWidth() | |||||
| || ((unsigned int) y) >= (unsigned int) component->getHeight()) | |||||
| if (((unsigned int) position.getX()) >= (unsigned int) component->getWidth() | |||||
| || ((unsigned int) position.getY()) >= (unsigned int) component->getHeight()) | |||||
| return false; | return false; | ||||
| CGPoint p; | CGPoint p; | ||||
| p.x = (float) x; | |||||
| p.y = (float) y; | |||||
| p.x = (float) position.getX(); | |||||
| p.y = (float) position.getY(); | |||||
| UIView* v = [view hitTest: p withEvent: nil]; | UIView* v = [view hitTest: p withEvent: nil]; | ||||
| @@ -159,7 +159,7 @@ public: | |||||
| bool isMinimised() const; | bool isMinimised() const; | ||||
| void setFullScreen (bool shouldBeFullScreen); | void setFullScreen (bool shouldBeFullScreen); | ||||
| bool isFullScreen() const; | bool isFullScreen() const; | ||||
| bool contains (int x, int y, bool trueIfInAChildWindow) const; | |||||
| bool contains (const Point<int>& position, bool trueIfInAChildWindow) const; | |||||
| const BorderSize getFrameSize() const; | const BorderSize getFrameSize() const; | ||||
| bool setAlwaysOnTop (bool alwaysOnTop); | bool setAlwaysOnTop (bool alwaysOnTop); | ||||
| void toFront (bool makeActiveWindow); | void toFront (bool makeActiveWindow); | ||||
| @@ -186,6 +186,7 @@ public: | |||||
| virtual void redirectMouseEnter (NSEvent* ev); | virtual void redirectMouseEnter (NSEvent* ev); | ||||
| virtual void redirectMouseExit (NSEvent* ev); | virtual void redirectMouseExit (NSEvent* ev); | ||||
| virtual void redirectMouseWheel (NSEvent* ev); | virtual void redirectMouseWheel (NSEvent* ev); | ||||
| void sendMouseEvent (NSEvent* ev); | |||||
| bool handleKeyEvent (NSEvent* ev, bool isKeyDown); | bool handleKeyEvent (NSEvent* ev, bool isKeyDown); | ||||
| virtual bool redirectKeyDown (NSEvent* ev); | virtual bool redirectKeyDown (NSEvent* ev); | ||||
| @@ -261,6 +262,10 @@ public: | |||||
| NSWindow* window; | NSWindow* window; | ||||
| JuceNSView* view; | JuceNSView* view; | ||||
| bool isSharedWindow, fullScreen, insideDrawRect, usingCoreGraphics, recursiveToFrontCall; | bool isSharedWindow, fullScreen, insideDrawRect, usingCoreGraphics, recursiveToFrontCall; | ||||
| static ModifierKeys currentModifiers; | |||||
| static ComponentPeer* currentlyFocusedPeer; | |||||
| static VoidArray keysCurrentlyDown; | |||||
| }; | }; | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -748,45 +753,37 @@ END_JUCE_NAMESPACE | |||||
| BEGIN_JUCE_NAMESPACE | BEGIN_JUCE_NAMESPACE | ||||
| //============================================================================== | //============================================================================== | ||||
| static ComponentPeer* currentlyFocusedPeer = 0; | |||||
| static VoidArray keysCurrentlyDown; | |||||
| ModifierKeys NSViewComponentPeer::currentModifiers; | |||||
| ComponentPeer* NSViewComponentPeer::currentlyFocusedPeer = 0; | |||||
| VoidArray NSViewComponentPeer::keysCurrentlyDown; | |||||
| //============================================================================== | |||||
| bool KeyPress::isKeyCurrentlyDown (const int keyCode) throw() | bool KeyPress::isKeyCurrentlyDown (const int keyCode) throw() | ||||
| { | { | ||||
| if (keysCurrentlyDown.contains ((void*) keyCode)) | |||||
| if (NSViewComponentPeer::keysCurrentlyDown.contains ((void*) keyCode)) | |||||
| return true; | return true; | ||||
| if (keyCode >= 'A' && keyCode <= 'Z' | if (keyCode >= 'A' && keyCode <= 'Z' | ||||
| && keysCurrentlyDown.contains ((void*) (int) CharacterFunctions::toLowerCase ((tchar) keyCode))) | |||||
| && NSViewComponentPeer::keysCurrentlyDown.contains ((void*) (int) CharacterFunctions::toLowerCase ((tchar) keyCode))) | |||||
| return true; | return true; | ||||
| if (keyCode >= 'a' && keyCode <= 'z' | if (keyCode >= 'a' && keyCode <= 'z' | ||||
| && keysCurrentlyDown.contains ((void*) (int) CharacterFunctions::toUpperCase ((tchar) keyCode))) | |||||
| && NSViewComponentPeer::keysCurrentlyDown.contains ((void*) (int) CharacterFunctions::toUpperCase ((tchar) keyCode))) | |||||
| return true; | return true; | ||||
| return false; | return false; | ||||
| } | } | ||||
| static int currentModifiers = 0; | |||||
| void NSViewComponentPeer::updateModifiers (NSEvent* e) | void NSViewComponentPeer::updateModifiers (NSEvent* e) | ||||
| { | { | ||||
| int m = currentModifiers & ~(ModifierKeys::shiftModifier | ModifierKeys::ctrlModifier | |||||
| | ModifierKeys::altModifier | ModifierKeys::commandModifier); | |||||
| if (([e modifierFlags] & NSShiftKeyMask) != 0) | |||||
| m |= ModifierKeys::shiftModifier; | |||||
| if (([e modifierFlags] & NSControlKeyMask) != 0) | |||||
| m |= ModifierKeys::ctrlModifier; | |||||
| int m = 0; | |||||
| if (([e modifierFlags] & NSAlternateKeyMask) != 0) | |||||
| m |= ModifierKeys::altModifier; | |||||
| if (([e modifierFlags] & NSShiftKeyMask) != 0) m |= ModifierKeys::shiftModifier; | |||||
| if (([e modifierFlags] & NSControlKeyMask) != 0) m |= ModifierKeys::ctrlModifier; | |||||
| if (([e modifierFlags] & NSAlternateKeyMask) != 0) m |= ModifierKeys::altModifier; | |||||
| if (([e modifierFlags] & NSCommandKeyMask) != 0) m |= ModifierKeys::commandModifier; | |||||
| if (([e modifierFlags] & NSCommandKeyMask) != 0) | |||||
| m |= ModifierKeys::commandModifier; | |||||
| currentModifiers = m; | |||||
| currentModifiers = currentModifiers.withOnlyMouseButtons().withFlags (m); | |||||
| } | } | ||||
| void NSViewComponentPeer::updateKeysDown (NSEvent* ev, bool isKeyDown) | void NSViewComponentPeer::updateKeysDown (NSEvent* ev, bool isKeyDown) | ||||
| @@ -805,12 +802,12 @@ void NSViewComponentPeer::updateKeysDown (NSEvent* ev, bool isKeyDown) | |||||
| const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() throw() | const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() throw() | ||||
| { | { | ||||
| return ModifierKeys (currentModifiers); | |||||
| return NSViewComponentPeer::currentModifiers; | |||||
| } | } | ||||
| void ModifierKeys::updateCurrentModifiers() throw() | void ModifierKeys::updateCurrentModifiers() throw() | ||||
| { | { | ||||
| currentModifierFlags = currentModifiers; | |||||
| currentModifiers = NSViewComponentPeer::currentModifiers; | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -1106,15 +1103,15 @@ bool NSViewComponentPeer::isFullScreen() const | |||||
| return fullScreen; | return fullScreen; | ||||
| } | } | ||||
| bool NSViewComponentPeer::contains (int x, int y, bool trueIfInAChildWindow) const | |||||
| bool NSViewComponentPeer::contains (const Point<int>& position, bool trueIfInAChildWindow) const | |||||
| { | { | ||||
| if (((unsigned int) x) >= (unsigned int) component->getWidth() | |||||
| || ((unsigned int) y) >= (unsigned int) component->getHeight()) | |||||
| if (((unsigned int) position.getX()) >= (unsigned int) component->getWidth() | |||||
| || ((unsigned int) position.getY()) >= (unsigned int) component->getHeight()) | |||||
| return false; | return false; | ||||
| NSPoint p; | NSPoint p; | ||||
| p.x = (float) x; | |||||
| p.y = (float) y; | |||||
| p.x = (float) position.getX(); | |||||
| p.y = (float) position.getY(); | |||||
| NSView* v = [view hitTest: p]; | NSView* v = [view hitTest: p]; | ||||
| @@ -1226,19 +1223,19 @@ void NSViewComponentPeer::viewFocusLoss() | |||||
| void juce_HandleProcessFocusChange() | void juce_HandleProcessFocusChange() | ||||
| { | { | ||||
| keysCurrentlyDown.clear(); | |||||
| NSViewComponentPeer::keysCurrentlyDown.clear(); | |||||
| if (NSViewComponentPeer::isValidPeer (currentlyFocusedPeer)) | |||||
| if (NSViewComponentPeer::isValidPeer (NSViewComponentPeer::currentlyFocusedPeer)) | |||||
| { | { | ||||
| if (Process::isForegroundProcess()) | if (Process::isForegroundProcess()) | ||||
| { | { | ||||
| currentlyFocusedPeer->handleFocusGain(); | |||||
| NSViewComponentPeer::currentlyFocusedPeer->handleFocusGain(); | |||||
| ComponentPeer::bringModalComponentToFront(); | ComponentPeer::bringModalComponentToFront(); | ||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| currentlyFocusedPeer->handleFocusLoss(); | |||||
| NSViewComponentPeer::currentlyFocusedPeer->handleFocusLoss(); | |||||
| // turn kiosk mode off if we lose focus.. | // turn kiosk mode off if we lose focus.. | ||||
| Desktop::getInstance().setKioskModeComponent (0); | Desktop::getInstance().setKioskModeComponent (0); | ||||
| @@ -1355,55 +1352,56 @@ bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev) | |||||
| #endif | #endif | ||||
| //============================================================================== | //============================================================================== | ||||
| void NSViewComponentPeer::redirectMouseDown (NSEvent* ev) | |||||
| void NSViewComponentPeer::sendMouseEvent (NSEvent* ev) | |||||
| { | { | ||||
| updateModifiers (ev); | updateModifiers (ev); | ||||
| currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]); | |||||
| handleMouseDown (getMousePos (ev, view), getMouseTime (ev)); | |||||
| handleMouseEvent (getMousePos (ev, view), currentModifiers, getMouseTime (ev)); | |||||
| } | |||||
| void NSViewComponentPeer::redirectMouseDown (NSEvent* ev) | |||||
| { | |||||
| currentModifiers = currentModifiers.withFlags (getModifierForButtonNumber ([ev buttonNumber])); | |||||
| sendMouseEvent (ev); | |||||
| } | } | ||||
| void NSViewComponentPeer::redirectMouseUp (NSEvent* ev) | void NSViewComponentPeer::redirectMouseUp (NSEvent* ev) | ||||
| { | { | ||||
| const int oldMods = currentModifiers; | |||||
| updateModifiers (ev); | |||||
| currentModifiers &= ~getModifierForButtonNumber ([ev buttonNumber]); | |||||
| handleMouseUp (oldMods, getMousePos (ev, view), getMouseTime (ev)); | |||||
| currentModifiers = currentModifiers.withoutFlags (getModifierForButtonNumber ([ev buttonNumber])); | |||||
| sendMouseEvent (ev); | |||||
| showArrowCursorIfNeeded(); | showArrowCursorIfNeeded(); | ||||
| } | } | ||||
| void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev) | void NSViewComponentPeer::redirectMouseDrag (NSEvent* ev) | ||||
| { | { | ||||
| updateModifiers (ev); | |||||
| currentModifiers |= getModifierForButtonNumber ([ev buttonNumber]); | |||||
| handleMouseDrag (getMousePos (ev, view), getMouseTime (ev)); | |||||
| currentModifiers = currentModifiers.withFlags (getModifierForButtonNumber ([ev buttonNumber])); | |||||
| sendMouseEvent (ev); | |||||
| } | } | ||||
| void NSViewComponentPeer::redirectMouseMove (NSEvent* ev) | void NSViewComponentPeer::redirectMouseMove (NSEvent* ev) | ||||
| { | { | ||||
| updateModifiers (ev); | |||||
| handleMouseMove (getMousePos (ev, view), getMouseTime (ev)); | |||||
| currentModifiers = currentModifiers.withoutMouseButtons(); | |||||
| sendMouseEvent (ev); | |||||
| showArrowCursorIfNeeded(); | showArrowCursorIfNeeded(); | ||||
| } | } | ||||
| void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev) | void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev) | ||||
| { | { | ||||
| updateModifiers (ev); | |||||
| handleMouseEnter (getMousePos (ev, view), getMouseTime (ev)); | |||||
| currentModifiers = currentModifiers.withoutMouseButtons(); | |||||
| sendMouseEvent (ev); | |||||
| } | } | ||||
| void NSViewComponentPeer::redirectMouseExit (NSEvent* ev) | void NSViewComponentPeer::redirectMouseExit (NSEvent* ev) | ||||
| { | { | ||||
| updateModifiers (ev); | |||||
| handleMouseExit (getMousePos (ev, view), getMouseTime (ev)); | |||||
| currentModifiers = currentModifiers.withoutMouseButtons(); | |||||
| sendMouseEvent (ev); | |||||
| } | } | ||||
| void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev) | void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev) | ||||
| { | { | ||||
| updateModifiers (ev); | updateModifiers (ev); | ||||
| handleMouseWheel (roundToInt ([ev deltaX] * 10.0f), | |||||
| roundToInt ([ev deltaY] * 10.0f), | |||||
| getMouseTime (ev)); | |||||
| handleMouseWheel (getMousePos (ev, view), getMouseTime (ev), | |||||
| [ev deltaX] * 10.0f, [ev deltaY] * 10.0f); | |||||
| } | } | ||||
| void NSViewComponentPeer::showArrowCursorIfNeeded() | void NSViewComponentPeer::showArrowCursorIfNeeded() | ||||
| @@ -27,223 +27,272 @@ | |||||
| // compiled on its own). | // compiled on its own). | ||||
| #if JUCE_INCLUDED_FILE | #if JUCE_INCLUDED_FILE | ||||
| //============================================================================== | |||||
| class JuceIStorage : public IStorage | |||||
| namespace ActiveXHelpers | |||||
| { | { | ||||
| int refCount; | |||||
| class JuceIStorage : public IStorage | |||||
| { | |||||
| int refCount; | |||||
| public: | |||||
| JuceIStorage() : refCount (1) {} | |||||
| public: | |||||
| JuceIStorage() : refCount (1) {} | |||||
| virtual ~JuceIStorage() | |||||
| { | |||||
| jassert (refCount == 0); | |||||
| } | |||||
| virtual ~JuceIStorage() | |||||
| { | |||||
| jassert (refCount == 0); | |||||
| } | |||||
| HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result) | |||||
| HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result) | |||||
| { | |||||
| if (id == IID_IUnknown || id == IID_IStorage) | |||||
| { | |||||
| AddRef(); | |||||
| *result = this; | |||||
| return S_OK; | |||||
| } | |||||
| *result = 0; | |||||
| return E_NOINTERFACE; | |||||
| } | |||||
| ULONG __stdcall AddRef() { return ++refCount; } | |||||
| ULONG __stdcall Release() { const int r = --refCount; if (r == 0) delete this; return r; } | |||||
| HRESULT __stdcall CreateStream (const WCHAR*, DWORD, DWORD, DWORD, IStream**) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall OpenStream (const WCHAR*, void*, DWORD, DWORD, IStream**) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall CreateStorage (const WCHAR*, DWORD, DWORD, DWORD, IStorage**) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall OpenStorage (const WCHAR*, IStorage*, DWORD, SNB, DWORD, IStorage**) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall CopyTo (DWORD, IID const*, SNB, IStorage*) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall MoveElementTo (const OLECHAR*,IStorage*, const OLECHAR*, DWORD) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall Commit (DWORD) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall Revert() { return E_NOTIMPL; } | |||||
| HRESULT __stdcall EnumElements (DWORD, void*, DWORD, IEnumSTATSTG**) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall DestroyElement (const OLECHAR*) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall RenameElement (const WCHAR*, const WCHAR*) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall SetElementTimes (const WCHAR*, FILETIME const*, FILETIME const*, FILETIME const*) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall SetClass (REFCLSID) { return S_OK; } | |||||
| HRESULT __stdcall SetStateBits (DWORD, DWORD) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall Stat (STATSTG*, DWORD) { return E_NOTIMPL; } | |||||
| juce_UseDebuggingNewOperator | |||||
| }; | |||||
| class JuceOleInPlaceFrame : public IOleInPlaceFrame | |||||
| { | { | ||||
| if (id == IID_IUnknown || id == IID_IStorage) | |||||
| int refCount; | |||||
| HWND window; | |||||
| public: | |||||
| JuceOleInPlaceFrame (HWND window_) | |||||
| : refCount (1), | |||||
| window (window_) | |||||
| { | { | ||||
| AddRef(); | |||||
| *result = this; | |||||
| return S_OK; | |||||
| } | } | ||||
| *result = 0; | |||||
| return E_NOINTERFACE; | |||||
| } | |||||
| virtual ~JuceOleInPlaceFrame() | |||||
| { | |||||
| jassert (refCount == 0); | |||||
| } | |||||
| ULONG __stdcall AddRef() { return ++refCount; } | |||||
| ULONG __stdcall Release() { const int r = --refCount; if (r == 0) delete this; return r; } | |||||
| HRESULT __stdcall CreateStream (const WCHAR*, DWORD, DWORD, DWORD, IStream**) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall OpenStream (const WCHAR*, void*, DWORD, DWORD, IStream**) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall CreateStorage (const WCHAR*, DWORD, DWORD, DWORD, IStorage**) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall OpenStorage (const WCHAR*, IStorage*, DWORD, SNB, DWORD, IStorage**) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall CopyTo (DWORD, IID const*, SNB, IStorage*) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall MoveElementTo (const OLECHAR*,IStorage*, const OLECHAR*, DWORD) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall Commit (DWORD) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall Revert() { return E_NOTIMPL; } | |||||
| HRESULT __stdcall EnumElements (DWORD, void*, DWORD, IEnumSTATSTG**) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall DestroyElement (const OLECHAR*) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall RenameElement (const WCHAR*, const WCHAR*) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall SetElementTimes (const WCHAR*, FILETIME const*, FILETIME const*, FILETIME const*) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall SetClass (REFCLSID) { return S_OK; } | |||||
| HRESULT __stdcall SetStateBits (DWORD, DWORD) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall Stat (STATSTG*, DWORD) { return E_NOTIMPL; } | |||||
| juce_UseDebuggingNewOperator | |||||
| }; | |||||
| HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result) | |||||
| { | |||||
| if (id == IID_IUnknown || id == IID_IOleInPlaceFrame) | |||||
| { | |||||
| AddRef(); | |||||
| *result = this; | |||||
| return S_OK; | |||||
| } | |||||
| *result = 0; | |||||
| return E_NOINTERFACE; | |||||
| } | |||||
| class JuceOleInPlaceFrame : public IOleInPlaceFrame | |||||
| { | |||||
| int refCount; | |||||
| HWND window; | |||||
| ULONG __stdcall AddRef() { return ++refCount; } | |||||
| ULONG __stdcall Release() { const int r = --refCount; if (r == 0) delete this; return r; } | |||||
| public: | |||||
| JuceOleInPlaceFrame (HWND window_) | |||||
| : refCount (1), | |||||
| window (window_) | |||||
| { | |||||
| } | |||||
| HRESULT __stdcall GetWindow (HWND* lphwnd) { *lphwnd = window; return S_OK; } | |||||
| HRESULT __stdcall ContextSensitiveHelp (BOOL) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall GetBorder (LPRECT) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall RequestBorderSpace (LPCBORDERWIDTHS) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall SetBorderSpace (LPCBORDERWIDTHS) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall SetActiveObject (IOleInPlaceActiveObject*, LPCOLESTR) { return S_OK; } | |||||
| HRESULT __stdcall InsertMenus (HMENU, LPOLEMENUGROUPWIDTHS) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall SetMenu (HMENU, HOLEMENU, HWND) { return S_OK; } | |||||
| HRESULT __stdcall RemoveMenus (HMENU) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall SetStatusText (LPCOLESTR) { return S_OK; } | |||||
| HRESULT __stdcall EnableModeless (BOOL) { return S_OK; } | |||||
| HRESULT __stdcall TranslateAccelerator(LPMSG, WORD) { return E_NOTIMPL; } | |||||
| juce_UseDebuggingNewOperator | |||||
| }; | |||||
| virtual ~JuceOleInPlaceFrame() | |||||
| { | |||||
| jassert (refCount == 0); | |||||
| } | |||||
| HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result) | |||||
| class JuceIOleInPlaceSite : public IOleInPlaceSite | |||||
| { | { | ||||
| if (id == IID_IUnknown || id == IID_IOleInPlaceFrame) | |||||
| int refCount; | |||||
| HWND window; | |||||
| JuceOleInPlaceFrame* frame; | |||||
| public: | |||||
| JuceIOleInPlaceSite (HWND window_) | |||||
| : refCount (1), | |||||
| window (window_) | |||||
| { | { | ||||
| AddRef(); | |||||
| *result = this; | |||||
| return S_OK; | |||||
| frame = new JuceOleInPlaceFrame (window); | |||||
| } | } | ||||
| *result = 0; | |||||
| return E_NOINTERFACE; | |||||
| } | |||||
| ULONG __stdcall AddRef() { return ++refCount; } | |||||
| ULONG __stdcall Release() { const int r = --refCount; if (r == 0) delete this; return r; } | |||||
| HRESULT __stdcall GetWindow (HWND* lphwnd) { *lphwnd = window; return S_OK; } | |||||
| HRESULT __stdcall ContextSensitiveHelp (BOOL) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall GetBorder (LPRECT) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall RequestBorderSpace (LPCBORDERWIDTHS) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall SetBorderSpace (LPCBORDERWIDTHS) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall SetActiveObject (IOleInPlaceActiveObject*, LPCOLESTR) { return S_OK; } | |||||
| HRESULT __stdcall InsertMenus (HMENU, LPOLEMENUGROUPWIDTHS) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall SetMenu (HMENU, HOLEMENU, HWND) { return S_OK; } | |||||
| HRESULT __stdcall RemoveMenus (HMENU) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall SetStatusText (LPCOLESTR) { return S_OK; } | |||||
| HRESULT __stdcall EnableModeless (BOOL) { return S_OK; } | |||||
| HRESULT __stdcall TranslateAccelerator(LPMSG, WORD) { return E_NOTIMPL; } | |||||
| juce_UseDebuggingNewOperator | |||||
| }; | |||||
| virtual ~JuceIOleInPlaceSite() | |||||
| { | |||||
| jassert (refCount == 0); | |||||
| frame->Release(); | |||||
| } | |||||
| HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result) | |||||
| { | |||||
| if (id == IID_IUnknown || id == IID_IOleInPlaceSite) | |||||
| { | |||||
| AddRef(); | |||||
| *result = this; | |||||
| return S_OK; | |||||
| } | |||||
| class JuceIOleInPlaceSite : public IOleInPlaceSite | |||||
| { | |||||
| int refCount; | |||||
| HWND window; | |||||
| JuceOleInPlaceFrame* frame; | |||||
| *result = 0; | |||||
| return E_NOINTERFACE; | |||||
| } | |||||
| public: | |||||
| JuceIOleInPlaceSite (HWND window_) | |||||
| : refCount (1), | |||||
| window (window_) | |||||
| { | |||||
| frame = new JuceOleInPlaceFrame (window); | |||||
| } | |||||
| ULONG __stdcall AddRef() { return ++refCount; } | |||||
| ULONG __stdcall Release() { const int r = --refCount; if (r == 0) delete this; return r; } | |||||
| virtual ~JuceIOleInPlaceSite() | |||||
| { | |||||
| jassert (refCount == 0); | |||||
| frame->Release(); | |||||
| } | |||||
| HRESULT __stdcall GetWindow (HWND* lphwnd) { *lphwnd = window; return S_OK; } | |||||
| HRESULT __stdcall ContextSensitiveHelp (BOOL) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall CanInPlaceActivate() { return S_OK; } | |||||
| HRESULT __stdcall OnInPlaceActivate() { return S_OK; } | |||||
| HRESULT __stdcall OnUIActivate() { return S_OK; } | |||||
| HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result) | |||||
| { | |||||
| if (id == IID_IUnknown || id == IID_IOleInPlaceSite) | |||||
| HRESULT __stdcall GetWindowContext (LPOLEINPLACEFRAME* lplpFrame, LPOLEINPLACEUIWINDOW* lplpDoc, LPRECT, LPRECT, LPOLEINPLACEFRAMEINFO lpFrameInfo) | |||||
| { | { | ||||
| AddRef(); | |||||
| *result = this; | |||||
| // frame->AddRef(); // MS docs are unclear about whether this is needed, but it seems to lead to a memory leak.. | |||||
| *lplpFrame = frame; | |||||
| *lplpDoc = 0; | |||||
| lpFrameInfo->fMDIApp = FALSE; | |||||
| lpFrameInfo->hwndFrame = window; | |||||
| lpFrameInfo->haccel = 0; | |||||
| lpFrameInfo->cAccelEntries = 0; | |||||
| return S_OK; | return S_OK; | ||||
| } | } | ||||
| *result = 0; | |||||
| return E_NOINTERFACE; | |||||
| } | |||||
| HRESULT __stdcall Scroll (SIZE) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall OnUIDeactivate (BOOL) { return S_OK; } | |||||
| HRESULT __stdcall OnInPlaceDeactivate() { return S_OK; } | |||||
| HRESULT __stdcall DiscardUndoState() { return E_NOTIMPL; } | |||||
| HRESULT __stdcall DeactivateAndUndo() { return E_NOTIMPL; } | |||||
| HRESULT __stdcall OnPosRectChange (LPCRECT) { return S_OK; } | |||||
| ULONG __stdcall AddRef() { return ++refCount; } | |||||
| ULONG __stdcall Release() { const int r = --refCount; if (r == 0) delete this; return r; } | |||||
| juce_UseDebuggingNewOperator | |||||
| }; | |||||
| HRESULT __stdcall GetWindow (HWND* lphwnd) { *lphwnd = window; return S_OK; } | |||||
| HRESULT __stdcall ContextSensitiveHelp (BOOL) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall CanInPlaceActivate() { return S_OK; } | |||||
| HRESULT __stdcall OnInPlaceActivate() { return S_OK; } | |||||
| HRESULT __stdcall OnUIActivate() { return S_OK; } | |||||
| HRESULT __stdcall GetWindowContext (LPOLEINPLACEFRAME* lplpFrame, LPOLEINPLACEUIWINDOW* lplpDoc, LPRECT, LPRECT, LPOLEINPLACEFRAMEINFO lpFrameInfo) | |||||
| class JuceIOleClientSite : public IOleClientSite | |||||
| { | { | ||||
| // frame->AddRef(); // MS docs are unclear about whether this is needed, but it seems to lead to a memory leak.. | |||||
| *lplpFrame = frame; | |||||
| *lplpDoc = 0; | |||||
| lpFrameInfo->fMDIApp = FALSE; | |||||
| lpFrameInfo->hwndFrame = window; | |||||
| lpFrameInfo->haccel = 0; | |||||
| lpFrameInfo->cAccelEntries = 0; | |||||
| return S_OK; | |||||
| } | |||||
| int refCount; | |||||
| JuceIOleInPlaceSite* inplaceSite; | |||||
| HRESULT __stdcall Scroll (SIZE) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall OnUIDeactivate (BOOL) { return S_OK; } | |||||
| HRESULT __stdcall OnInPlaceDeactivate() { return S_OK; } | |||||
| HRESULT __stdcall DiscardUndoState() { return E_NOTIMPL; } | |||||
| HRESULT __stdcall DeactivateAndUndo() { return E_NOTIMPL; } | |||||
| HRESULT __stdcall OnPosRectChange (LPCRECT) { return S_OK; } | |||||
| public: | |||||
| JuceIOleClientSite (HWND window) | |||||
| : refCount (1) | |||||
| { | |||||
| inplaceSite = new JuceIOleInPlaceSite (window); | |||||
| } | |||||
| juce_UseDebuggingNewOperator | |||||
| }; | |||||
| virtual ~JuceIOleClientSite() | |||||
| { | |||||
| jassert (refCount == 0); | |||||
| inplaceSite->Release(); | |||||
| } | |||||
| HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result) | |||||
| { | |||||
| if (id == IID_IUnknown || id == IID_IOleClientSite) | |||||
| { | |||||
| AddRef(); | |||||
| *result = this; | |||||
| return S_OK; | |||||
| } | |||||
| else if (id == IID_IOleInPlaceSite) | |||||
| { | |||||
| inplaceSite->AddRef(); | |||||
| *result = inplaceSite; | |||||
| return S_OK; | |||||
| } | |||||
| class JuceIOleClientSite : public IOleClientSite | |||||
| { | |||||
| int refCount; | |||||
| JuceIOleInPlaceSite* inplaceSite; | |||||
| *result = 0; | |||||
| return E_NOINTERFACE; | |||||
| } | |||||
| public: | |||||
| JuceIOleClientSite (HWND window) | |||||
| : refCount (1) | |||||
| { | |||||
| inplaceSite = new JuceIOleInPlaceSite (window); | |||||
| } | |||||
| ULONG __stdcall AddRef() { return ++refCount; } | |||||
| ULONG __stdcall Release() { const int r = --refCount; if (r == 0) delete this; return r; } | |||||
| virtual ~JuceIOleClientSite() | |||||
| { | |||||
| jassert (refCount == 0); | |||||
| inplaceSite->Release(); | |||||
| } | |||||
| HRESULT __stdcall SaveObject() { return E_NOTIMPL; } | |||||
| HRESULT __stdcall GetMoniker (DWORD, DWORD, IMoniker**) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall GetContainer (LPOLECONTAINER* ppContainer) { *ppContainer = 0; return E_NOINTERFACE; } | |||||
| HRESULT __stdcall ShowObject() { return S_OK; } | |||||
| HRESULT __stdcall OnShowWindow (BOOL) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall RequestNewObjectLayout() { return E_NOTIMPL; } | |||||
| juce_UseDebuggingNewOperator | |||||
| }; | |||||
| HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result) | |||||
| //============================================================================== | |||||
| static VoidArray activeXComps; | |||||
| static HWND getHWND (const ActiveXControlComponent* const component) | |||||
| { | { | ||||
| if (id == IID_IUnknown || id == IID_IOleClientSite) | |||||
| { | |||||
| AddRef(); | |||||
| *result = this; | |||||
| return S_OK; | |||||
| } | |||||
| else if (id == IID_IOleInPlaceSite) | |||||
| HWND hwnd = 0; | |||||
| const IID iid = IID_IOleWindow; | |||||
| IOleWindow* const window = (IOleWindow*) component->queryInterface (&iid); | |||||
| if (window != 0) | |||||
| { | { | ||||
| inplaceSite->AddRef(); | |||||
| *result = inplaceSite; | |||||
| return S_OK; | |||||
| window->GetWindow (&hwnd); | |||||
| window->Release(); | |||||
| } | } | ||||
| *result = 0; | |||||
| return E_NOINTERFACE; | |||||
| return hwnd; | |||||
| } | } | ||||
| ULONG __stdcall AddRef() { return ++refCount; } | |||||
| ULONG __stdcall Release() { const int r = --refCount; if (r == 0) delete this; return r; } | |||||
| static void offerActiveXMouseEventToPeer (ComponentPeer* const peer, HWND hwnd, UINT message, LPARAM lParam) | |||||
| { | |||||
| RECT activeXRect, peerRect; | |||||
| GetWindowRect (hwnd, &activeXRect); | |||||
| GetWindowRect ((HWND) peer->getNativeHandle(), &peerRect); | |||||
| HRESULT __stdcall SaveObject() { return E_NOTIMPL; } | |||||
| HRESULT __stdcall GetMoniker (DWORD, DWORD, IMoniker**) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall GetContainer (LPOLECONTAINER* ppContainer) { *ppContainer = 0; return E_NOINTERFACE; } | |||||
| HRESULT __stdcall ShowObject() { return S_OK; } | |||||
| HRESULT __stdcall OnShowWindow (BOOL) { return E_NOTIMPL; } | |||||
| HRESULT __stdcall RequestNewObjectLayout() { return E_NOTIMPL; } | |||||
| const Point<int> mousePos (GET_X_LPARAM (lParam) + activeXRect.left - peerRect.left, | |||||
| GET_Y_LPARAM (lParam) + activeXRect.top - peerRect.top); | |||||
| const int64 mouseEventTime = Win32ComponentPeer::getMouseEventTime(); | |||||
| juce_UseDebuggingNewOperator | |||||
| }; | |||||
| ModifierKeys::getCurrentModifiersRealtime(); // to update the mouse button flags | |||||
| switch (message) | |||||
| { | |||||
| case WM_MOUSEMOVE: | |||||
| case WM_LBUTTONDOWN: | |||||
| case WM_MBUTTONDOWN: | |||||
| case WM_RBUTTONDOWN: | |||||
| case WM_LBUTTONUP: | |||||
| case WM_MBUTTONUP: | |||||
| case WM_RBUTTONUP: | |||||
| peer->handleMouseEvent (mousePos, Win32ComponentPeer::currentModifiers, mouseEventTime); | |||||
| break; | |||||
| default: | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| class ActiveXControlData : public ComponentMovementWatcher | |||||
| class ActiveXControlComponent::ActiveXControlData : public ComponentMovementWatcher | |||||
| { | { | ||||
| ActiveXControlComponent* const owner; | ActiveXControlComponent* const owner; | ||||
| bool wasShowing; | bool wasShowing; | ||||
| @@ -261,8 +310,8 @@ public: | |||||
| owner (owner_), | owner (owner_), | ||||
| wasShowing (owner_ != 0 && owner_->isShowing()), | wasShowing (owner_ != 0 && owner_->isShowing()), | ||||
| controlHWND (0), | controlHWND (0), | ||||
| storage (new JuceIStorage()), | |||||
| clientSite (new JuceIOleClientSite (hwnd)), | |||||
| storage (new ActiveXHelpers::JuceIStorage()), | |||||
| clientSite (new ActiveXHelpers::JuceIOleClientSite (hwnd)), | |||||
| control (0) | control (0) | ||||
| { | { | ||||
| } | } | ||||
| @@ -315,124 +364,66 @@ public: | |||||
| return ((ActiveXControlData*) ax->control) != 0 | return ((ActiveXControlData*) ax->control) != 0 | ||||
| && ((ActiveXControlData*) ax->control)->controlHWND == hwnd; | && ((ActiveXControlData*) ax->control)->controlHWND == hwnd; | ||||
| } | } | ||||
| }; | |||||
| //============================================================================== | |||||
| static VoidArray activeXComps; | |||||
| static HWND getHWND (const ActiveXControlComponent* const component) | |||||
| { | |||||
| HWND hwnd = 0; | |||||
| const IID iid = IID_IOleWindow; | |||||
| IOleWindow* const window = (IOleWindow*) component->queryInterface (&iid); | |||||
| if (window != 0) | |||||
| { | |||||
| window->GetWindow (&hwnd); | |||||
| window->Release(); | |||||
| } | |||||
| return hwnd; | |||||
| } | |||||
| static void offerActiveXMouseEventToPeer (ComponentPeer* const peer, HWND hwnd, UINT message, LPARAM lParam) | |||||
| { | |||||
| RECT activeXRect, peerRect; | |||||
| GetWindowRect (hwnd, &activeXRect); | |||||
| GetWindowRect ((HWND) peer->getNativeHandle(), &peerRect); | |||||
| const Point<int> mousePos (GET_X_LPARAM (lParam) + activeXRect.left - peerRect.left, | |||||
| GET_Y_LPARAM (lParam) + activeXRect.top - peerRect.top); | |||||
| const int64 mouseEventTime = getMouseEventTime(); | |||||
| const int oldModifiers = currentModifiers; | |||||
| ModifierKeys::getCurrentModifiersRealtime(); // to update the mouse button flags | |||||
| switch (message) | |||||
| { | |||||
| case WM_MOUSEMOVE: | |||||
| if (ModifierKeys (currentModifiers).isAnyMouseButtonDown()) | |||||
| peer->handleMouseDrag (mousePos, mouseEventTime); | |||||
| else | |||||
| peer->handleMouseMove (mousePos, mouseEventTime); | |||||
| break; | |||||
| case WM_LBUTTONDOWN: | |||||
| case WM_MBUTTONDOWN: | |||||
| case WM_RBUTTONDOWN: | |||||
| peer->handleMouseDown (mousePos, mouseEventTime); | |||||
| break; | |||||
| case WM_LBUTTONUP: | |||||
| case WM_MBUTTONUP: | |||||
| case WM_RBUTTONUP: | |||||
| peer->handleMouseUp (oldModifiers, mousePos, mouseEventTime); | |||||
| break; | |||||
| default: | |||||
| break; | |||||
| } | |||||
| } | |||||
| // intercepts events going to an activeX control, so we can sneakily use the mouse events | |||||
| static LRESULT CALLBACK activeXHookWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) | |||||
| { | |||||
| for (int i = activeXComps.size(); --i >= 0;) | |||||
| // intercepts events going to an activeX control, so we can sneakily use the mouse events | |||||
| static LRESULT CALLBACK activeXHookWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) | |||||
| { | { | ||||
| const ActiveXControlComponent* const ax = (const ActiveXControlComponent*) activeXComps.getUnchecked(i); | |||||
| if (ActiveXControlData::doesWindowMatch (ax, hwnd)) | |||||
| for (int i = ActiveXHelpers::activeXComps.size(); --i >= 0;) | |||||
| { | { | ||||
| switch (message) | |||||
| const ActiveXControlComponent* const ax = (const ActiveXControlComponent*) ActiveXHelpers::activeXComps.getUnchecked(i); | |||||
| if (doesWindowMatch (ax, hwnd)) | |||||
| { | { | ||||
| case WM_MOUSEMOVE: | |||||
| case WM_LBUTTONDOWN: | |||||
| case WM_MBUTTONDOWN: | |||||
| case WM_RBUTTONDOWN: | |||||
| case WM_LBUTTONUP: | |||||
| case WM_MBUTTONUP: | |||||
| case WM_RBUTTONUP: | |||||
| case WM_LBUTTONDBLCLK: | |||||
| case WM_MBUTTONDBLCLK: | |||||
| case WM_RBUTTONDBLCLK: | |||||
| if (ax->isShowing()) | |||||
| switch (message) | |||||
| { | { | ||||
| ComponentPeer* const peer = ax->getPeer(); | |||||
| if (peer != 0) | |||||
| case WM_MOUSEMOVE: | |||||
| case WM_LBUTTONDOWN: | |||||
| case WM_MBUTTONDOWN: | |||||
| case WM_RBUTTONDOWN: | |||||
| case WM_LBUTTONUP: | |||||
| case WM_MBUTTONUP: | |||||
| case WM_RBUTTONUP: | |||||
| case WM_LBUTTONDBLCLK: | |||||
| case WM_MBUTTONDBLCLK: | |||||
| case WM_RBUTTONDBLCLK: | |||||
| if (ax->isShowing()) | |||||
| { | { | ||||
| offerActiveXMouseEventToPeer (peer, hwnd, message, lParam); | |||||
| ComponentPeer* const peer = ax->getPeer(); | |||||
| if (! ax->areMouseEventsAllowed()) | |||||
| return 0; | |||||
| if (peer != 0) | |||||
| { | |||||
| ActiveXHelpers::offerActiveXMouseEventToPeer (peer, hwnd, message, lParam); | |||||
| if (! ax->areMouseEventsAllowed()) | |||||
| return 0; | |||||
| } | |||||
| } | } | ||||
| break; | |||||
| default: | |||||
| break; | |||||
| } | } | ||||
| break; | |||||
| default: | |||||
| break; | |||||
| return CallWindowProc ((WNDPROC) (ax->originalWndProc), hwnd, message, wParam, lParam); | |||||
| } | } | ||||
| return CallWindowProc ((WNDPROC) (ax->originalWndProc), hwnd, message, wParam, lParam); | |||||
| } | } | ||||
| } | |||||
| return DefWindowProc (hwnd, message, wParam, lParam); | |||||
| } | |||||
| return DefWindowProc (hwnd, message, wParam, lParam); | |||||
| } | |||||
| }; | |||||
| ActiveXControlComponent::ActiveXControlComponent() | ActiveXControlComponent::ActiveXControlComponent() | ||||
| : originalWndProc (0), | : originalWndProc (0), | ||||
| control (0), | control (0), | ||||
| mouseEventsAllowed (true) | mouseEventsAllowed (true) | ||||
| { | { | ||||
| activeXComps.add (this); | |||||
| ActiveXHelpers::activeXComps.add (this); | |||||
| } | } | ||||
| ActiveXControlComponent::~ActiveXControlComponent() | ActiveXControlComponent::~ActiveXControlComponent() | ||||
| { | { | ||||
| deleteControl(); | deleteControl(); | ||||
| activeXComps.removeValue (this); | |||||
| ActiveXHelpers::activeXComps.removeValue (this); | |||||
| } | } | ||||
| void ActiveXControlComponent::paint (Graphics& g) | void ActiveXControlComponent::paint (Graphics& g) | ||||
| @@ -476,12 +467,12 @@ bool ActiveXControlComponent::createControl (const void* controlIID) | |||||
| control = info.release(); | control = info.release(); | ||||
| setControlBounds (Rectangle<int> (pos.getX(), pos.getY(), getWidth(), getHeight())); | setControlBounds (Rectangle<int> (pos.getX(), pos.getY(), getWidth(), getHeight())); | ||||
| ((ActiveXControlData*) control)->controlHWND = getHWND (this); | |||||
| ((ActiveXControlData*) control)->controlHWND = ActiveXHelpers::getHWND (this); | |||||
| if (((ActiveXControlData*) control)->controlHWND != 0) | if (((ActiveXControlData*) control)->controlHWND != 0) | ||||
| { | { | ||||
| originalWndProc = (void*) (pointer_sized_int) GetWindowLongPtr ((HWND) ((ActiveXControlData*) control)->controlHWND, GWLP_WNDPROC); | originalWndProc = (void*) (pointer_sized_int) GetWindowLongPtr ((HWND) ((ActiveXControlData*) control)->controlHWND, GWLP_WNDPROC); | ||||
| SetWindowLongPtr ((HWND) ((ActiveXControlData*) control)->controlHWND, GWLP_WNDPROC, (LONG_PTR) activeXHookWndProc); | |||||
| SetWindowLongPtr ((HWND) ((ActiveXControlData*) control)->controlHWND, GWLP_WNDPROC, (LONG_PTR) ActiveXControlData::activeXHookWndProc); | |||||
| } | } | ||||
| return true; | return true; | ||||
| @@ -336,33 +336,6 @@ long improbableWindowNumber = 0xf965aa01; // also referenced by messaging.cpp | |||||
| //============================================================================== | //============================================================================== | ||||
| static int currentModifiers = 0; | |||||
| static int modifiersAtLastCallback = 0; | |||||
| static void updateKeyModifiers() throw() | |||||
| { | |||||
| currentModifiers &= ~(ModifierKeys::shiftModifier | |||||
| | ModifierKeys::ctrlModifier | |||||
| | ModifierKeys::altModifier); | |||||
| if ((GetKeyState (VK_SHIFT) & 0x8000) != 0) | |||||
| currentModifiers |= ModifierKeys::shiftModifier; | |||||
| if ((GetKeyState (VK_CONTROL) & 0x8000) != 0) | |||||
| currentModifiers |= ModifierKeys::ctrlModifier; | |||||
| if ((GetKeyState (VK_MENU) & 0x8000) != 0) | |||||
| currentModifiers |= ModifierKeys::altModifier; | |||||
| if ((GetKeyState (VK_RMENU) & 0x8000) != 0) | |||||
| currentModifiers &= ~(ModifierKeys::ctrlModifier | ModifierKeys::altModifier); | |||||
| } | |||||
| void ModifierKeys::updateCurrentModifiers() throw() | |||||
| { | |||||
| currentModifierFlags = currentModifiers; | |||||
| } | |||||
| bool KeyPress::isKeyCurrentlyDown (const int keyCode) throw() | bool KeyPress::isKeyCurrentlyDown (const int keyCode) throw() | ||||
| { | { | ||||
| SHORT k = (SHORT) keyCode; | SHORT k = (SHORT) keyCode; | ||||
| @@ -389,39 +362,6 @@ bool KeyPress::isKeyCurrentlyDown (const int keyCode) throw() | |||||
| return (GetKeyState (k) & 0x8000) != 0; | return (GetKeyState (k) & 0x8000) != 0; | ||||
| } | } | ||||
| const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() throw() | |||||
| { | |||||
| updateKeyModifiers(); | |||||
| currentModifiers &= ~ModifierKeys::allMouseButtonModifiers; | |||||
| if ((GetKeyState (VK_LBUTTON) & 0x8000) != 0) | |||||
| currentModifiers |= ModifierKeys::leftButtonModifier; | |||||
| if ((GetKeyState (VK_RBUTTON) & 0x8000) != 0) | |||||
| currentModifiers |= ModifierKeys::rightButtonModifier; | |||||
| if ((GetKeyState (VK_MBUTTON) & 0x8000) != 0) | |||||
| currentModifiers |= ModifierKeys::middleButtonModifier; | |||||
| return ModifierKeys (currentModifiers); | |||||
| } | |||||
| static int64 getMouseEventTime() throw() | |||||
| { | |||||
| static int64 eventTimeOffset = 0; | |||||
| static DWORD lastMessageTime = 0; | |||||
| const DWORD thisMessageTime = GetMessageTime(); | |||||
| if (thisMessageTime < lastMessageTime || lastMessageTime == 0) | |||||
| { | |||||
| lastMessageTime = thisMessageTime; | |||||
| eventTimeOffset = Time::currentTimeMillis() - thisMessageTime; | |||||
| } | |||||
| return eventTimeOffset + thisMessageTime; | |||||
| } | |||||
| static void* callFunctionIfNotLocked (MessageCallbackFunction* callback, void* userData) | static void* callFunctionIfNotLocked (MessageCallbackFunction* callback, void* userData) | ||||
| { | { | ||||
| if (MessageManager::getInstance()->currentThreadHasLockedMessageManager()) | if (MessageManager::getInstance()->currentThreadHasLockedMessageManager()) | ||||
| @@ -666,17 +606,20 @@ public: | |||||
| return wp.showCmd == SW_SHOWMAXIMIZED; | return wp.showCmd == SW_SHOWMAXIMIZED; | ||||
| } | } | ||||
| bool contains (int x, int y, bool trueIfInAChildWindow) const | |||||
| bool contains (const Point<int>& position, bool trueIfInAChildWindow) const | |||||
| { | { | ||||
| if (((unsigned int) position.getX()) >= (unsigned int) component->getWidth() | |||||
| || ((unsigned int) position.getY()) >= (unsigned int) component->getHeight()) | |||||
| return false; | |||||
| RECT r; | RECT r; | ||||
| GetWindowRect (hwnd, &r); | GetWindowRect (hwnd, &r); | ||||
| POINT p; | POINT p; | ||||
| p.x = x + r.left + windowBorder.getLeft(); | |||||
| p.y = y + r.top + windowBorder.getTop(); | |||||
| p.x = position.getX() + r.left + windowBorder.getLeft(); | |||||
| p.y = position.getY() + r.top + windowBorder.getTop(); | |||||
| HWND w = WindowFromPoint (p); | HWND w = WindowFromPoint (p); | ||||
| return w == hwnd || (trueIfInAChildWindow && (IsChild (hwnd, w) != 0)); | return w == hwnd || (trueIfInAChildWindow && (IsChild (hwnd, w) != 0)); | ||||
| } | } | ||||
| @@ -849,11 +792,52 @@ public: | |||||
| return GetAncestor (hwnd, GA_ROOT) == h; | return GetAncestor (hwnd, GA_ROOT) == h; | ||||
| } | } | ||||
| //============================================================================== | |||||
| static void updateKeyModifiers() throw() | |||||
| { | |||||
| int keyMods = 0; | |||||
| if (GetKeyState (VK_SHIFT) & 0x8000) keyMods |= ModifierKeys::shiftModifier; | |||||
| if (GetKeyState (VK_CONTROL) & 0x8000) keyMods |= ModifierKeys::ctrlModifier; | |||||
| if (GetKeyState (VK_MENU) & 0x8000) keyMods |= ModifierKeys::altModifier; | |||||
| if (GetKeyState (VK_RMENU) & 0x8000) keyMods &= ~(ModifierKeys::ctrlModifier | ModifierKeys::altModifier); | |||||
| currentModifiers = currentModifiers.withOnlyMouseButtons().withFlags (keyMods); | |||||
| } | |||||
| static void updateModifiersFromWParam (const WPARAM wParam) | |||||
| { | |||||
| int mouseMods = 0; | |||||
| if (wParam & MK_LBUTTON) mouseMods |= ModifierKeys::leftButtonModifier; | |||||
| if (wParam & MK_RBUTTON) mouseMods |= ModifierKeys::rightButtonModifier; | |||||
| if (wParam & MK_MBUTTON) mouseMods |= ModifierKeys::middleButtonModifier; | |||||
| currentModifiers = currentModifiers.withoutMouseButtons().withFlags (mouseMods); | |||||
| updateKeyModifiers(); | |||||
| } | |||||
| static int64 getMouseEventTime() | |||||
| { | |||||
| static int64 eventTimeOffset = 0; | |||||
| static DWORD lastMessageTime = 0; | |||||
| const DWORD thisMessageTime = GetMessageTime(); | |||||
| if (thisMessageTime < lastMessageTime || lastMessageTime == 0) | |||||
| { | |||||
| lastMessageTime = thisMessageTime; | |||||
| eventTimeOffset = Time::currentTimeMillis() - thisMessageTime; | |||||
| } | |||||
| return eventTimeOffset + thisMessageTime; | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| bool dontRepaint; | bool dontRepaint; | ||||
| static ModifierKeys currentModifiers; | |||||
| static ModifierKeys modifiersAtLastCallback; | |||||
| private: | private: | ||||
| HWND hwnd; | HWND hwnd; | ||||
| DropShadower* shadower; | DropShadower* shadower; | ||||
| @@ -1257,19 +1241,17 @@ private: | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| void doMouseMove (const int x, const int y) | |||||
| void doMouseEvent (const Point<int>& position) | |||||
| { | { | ||||
| static uint32 lastMouseTime = 0; | |||||
| // this can be set to throttle the mouse-messages to less than a | |||||
| // certain number per second, as things can get unresponsive | |||||
| // if each drag or move callback has to do a lot of work. | |||||
| const int maxMouseMovesPerSecond = 60; | |||||
| const int64 mouseEventTime = getMouseEventTime(); | |||||
| handleMouseEvent (position, currentModifiers, getMouseEventTime()); | |||||
| } | |||||
| void doMouseMove (const Point<int>& position) | |||||
| { | |||||
| if (! isMouseOver) | if (! isMouseOver) | ||||
| { | { | ||||
| isMouseOver = true; | isMouseOver = true; | ||||
| updateKeyModifiers(); | |||||
| TRACKMOUSEEVENT tme; | TRACKMOUSEEVENT tme; | ||||
| tme.cbSize = sizeof (tme); | tme.cbSize = sizeof (tme); | ||||
| @@ -1278,151 +1260,63 @@ private: | |||||
| tme.dwHoverTime = 0; | tme.dwHoverTime = 0; | ||||
| if (! TrackMouseEvent (&tme)) | if (! TrackMouseEvent (&tme)) | ||||
| { | |||||
| jassertfalse; | jassertfalse; | ||||
| } | |||||
| updateKeyModifiers(); | |||||
| handleMouseEnter (Point<int> (x, y), mouseEventTime); | |||||
| } | } | ||||
| else if (! isDragging) | else if (! isDragging) | ||||
| { | { | ||||
| if (((unsigned int) x) < (unsigned int) component->getWidth() | |||||
| && ((unsigned int) y) < (unsigned int) component->getHeight()) | |||||
| { | |||||
| RECT r; | |||||
| GetWindowRect (hwnd, &r); | |||||
| POINT p; | |||||
| p.x = x + r.left + windowBorder.getLeft(); | |||||
| p.y = y + r.top + windowBorder.getTop(); | |||||
| if (WindowFromPoint (p) == hwnd) | |||||
| { | |||||
| const uint32 now = Time::getMillisecondCounter(); | |||||
| if (now > lastMouseTime + 1000 / maxMouseMovesPerSecond) | |||||
| { | |||||
| lastMouseTime = now; | |||||
| handleMouseMove (Point<int> (x, y), mouseEventTime); | |||||
| } | |||||
| } | |||||
| } | |||||
| if (! contains (position, false)) | |||||
| return; | |||||
| } | } | ||||
| else | |||||
| { | |||||
| const uint32 now = Time::getMillisecondCounter(); | |||||
| if (now > lastMouseTime + 1000 / maxMouseMovesPerSecond) | |||||
| { | |||||
| lastMouseTime = now; | |||||
| handleMouseDrag (Point<int> (x, y), mouseEventTime); | |||||
| } | |||||
| } | |||||
| doMouseEvent (position); | |||||
| } | } | ||||
| void doMouseDown (const int x, const int y, const WPARAM wParam) | |||||
| void doMouseDown (const Point<int>& position, const WPARAM wParam) | |||||
| { | { | ||||
| if (GetCapture() != hwnd) | if (GetCapture() != hwnd) | ||||
| SetCapture (hwnd); | SetCapture (hwnd); | ||||
| doMouseMove (x, y); | |||||
| currentModifiers &= ~ModifierKeys::allMouseButtonModifiers; | |||||
| if ((wParam & MK_LBUTTON) != 0) | |||||
| currentModifiers |= ModifierKeys::leftButtonModifier; | |||||
| if ((wParam & MK_RBUTTON) != 0) | |||||
| currentModifiers |= ModifierKeys::rightButtonModifier; | |||||
| if ((wParam & MK_MBUTTON) != 0) | |||||
| currentModifiers |= ModifierKeys::middleButtonModifier; | |||||
| doMouseMove (position); | |||||
| updateKeyModifiers(); | |||||
| updateModifiersFromWParam (wParam); | |||||
| isDragging = true; | isDragging = true; | ||||
| handleMouseDown (Point<int> (x, y), getMouseEventTime()); | |||||
| doMouseEvent (position); | |||||
| } | } | ||||
| void doMouseUp (const int x, const int y, const WPARAM wParam) | |||||
| void doMouseUp (const Point<int>& position, const WPARAM wParam) | |||||
| { | { | ||||
| int numButtons = 0; | |||||
| if ((wParam & MK_LBUTTON) != 0) | |||||
| ++numButtons; | |||||
| if ((wParam & MK_RBUTTON) != 0) | |||||
| ++numButtons; | |||||
| if ((wParam & MK_MBUTTON) != 0) | |||||
| ++numButtons; | |||||
| const int oldModifiers = currentModifiers; | |||||
| // update the currentmodifiers only after the callback, so the callback | |||||
| // knows which button was released. | |||||
| currentModifiers &= ~ModifierKeys::allMouseButtonModifiers; | |||||
| if ((wParam & MK_LBUTTON) != 0) | |||||
| currentModifiers |= ModifierKeys::leftButtonModifier; | |||||
| if ((wParam & MK_RBUTTON) != 0) | |||||
| currentModifiers |= ModifierKeys::rightButtonModifier; | |||||
| if ((wParam & MK_MBUTTON) != 0) | |||||
| currentModifiers |= ModifierKeys::middleButtonModifier; | |||||
| updateKeyModifiers(); | |||||
| updateModifiersFromWParam (wParam); | |||||
| isDragging = false; | isDragging = false; | ||||
| // release the mouse capture if the user's not still got a button down | |||||
| if (numButtons == 0 && hwnd == GetCapture()) | |||||
| // release the mouse capture if the user has released all buttons | |||||
| if ((wParam & (MK_LBUTTON | MK_RBUTTON | MK_MBUTTON)) == 0 && hwnd == GetCapture()) | |||||
| ReleaseCapture(); | ReleaseCapture(); | ||||
| handleMouseUp (oldModifiers, Point<int> (x, y), getMouseEventTime()); | |||||
| doMouseEvent (position); | |||||
| } | } | ||||
| void doCaptureChanged() | void doCaptureChanged() | ||||
| { | { | ||||
| if (isDragging) | if (isDragging) | ||||
| { | |||||
| RECT wr; | |||||
| GetWindowRect (hwnd, &wr); | |||||
| const DWORD mp = GetMessagePos(); | |||||
| doMouseUp (GET_X_LPARAM (mp) - wr.left - windowBorder.getLeft(), | |||||
| GET_Y_LPARAM (mp) - wr.top - windowBorder.getTop(), | |||||
| (WPARAM) getMouseEventTime()); | |||||
| } | |||||
| doMouseUp (getCurrentMousePos(), (WPARAM) 0); | |||||
| } | } | ||||
| void doMouseExit() | void doMouseExit() | ||||
| { | { | ||||
| if (isMouseOver) | |||||
| { | |||||
| isMouseOver = false; | |||||
| RECT wr; | |||||
| GetWindowRect (hwnd, &wr); | |||||
| const DWORD mp = GetMessagePos(); | |||||
| handleMouseExit (Point<int> (GET_X_LPARAM (mp) - wr.left - windowBorder.getLeft(), | |||||
| GET_Y_LPARAM (mp) - wr.top - windowBorder.getTop()), | |||||
| getMouseEventTime()); | |||||
| } | |||||
| isMouseOver = false; | |||||
| doMouseEvent (getCurrentMousePos()); | |||||
| } | } | ||||
| void doMouseWheel (const WPARAM wParam, const bool isVertical) | |||||
| void doMouseWheel (const Point<int>& position, const WPARAM wParam, const bool isVertical) | |||||
| { | { | ||||
| updateKeyModifiers(); | updateKeyModifiers(); | ||||
| const int amount = jlimit (-1000, 1000, (int) (0.75f * (short) HIWORD (wParam))); | |||||
| const float amount = jlimit (-1000.0f, 1000.0f, 0.75f * HIWORD (wParam)); | |||||
| handleMouseWheel (isVertical ? 0 : amount, | |||||
| isVertical ? amount : 0, | |||||
| getMouseEventTime()); | |||||
| handleMouseWheel (position, getMouseEventTime(), | |||||
| isVertical ? 0.0f : amount, | |||||
| isVertical ? amount : 0.0f); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -1592,7 +1486,7 @@ private: | |||||
| key = (int) keyChar; | key = (int) keyChar; | ||||
| // avoid sending junk text characters for some control-key combinations | // avoid sending junk text characters for some control-key combinations | ||||
| if (textChar < ' ' && (currentModifiers & (ModifierKeys::ctrlModifier | ModifierKeys::altModifier)) != 0) | |||||
| if (textChar < ' ' && currentModifiers.testFlags (ModifierKeys::ctrlModifier | ModifierKeys::altModifier)) | |||||
| textChar = 0; | textChar = 0; | ||||
| } | } | ||||
| @@ -1784,6 +1678,21 @@ public: | |||||
| } | } | ||||
| private: | private: | ||||
| static const Point<int> getPointFromLParam (LPARAM lParam) throw() | |||||
| { | |||||
| return Point<int> (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam)); | |||||
| } | |||||
| const Point<int> getCurrentMousePos() throw() | |||||
| { | |||||
| RECT wr; | |||||
| GetWindowRect (hwnd, &wr); | |||||
| const DWORD mp = GetMessagePos(); | |||||
| return Point<int> (GET_X_LPARAM (mp) - wr.left - windowBorder.getLeft(), | |||||
| GET_Y_LPARAM (mp) - wr.top - windowBorder.getTop()); | |||||
| } | |||||
| LRESULT peerWindowProc (HWND h, UINT message, WPARAM wParam, LPARAM lParam) | LRESULT peerWindowProc (HWND h, UINT message, WPARAM wParam, LPARAM lParam) | ||||
| { | { | ||||
| if (isValidPeer (this)) | if (isValidPeer (this)) | ||||
| @@ -1823,7 +1732,7 @@ private: | |||||
| //============================================================================== | //============================================================================== | ||||
| case WM_MOUSEMOVE: | case WM_MOUSEMOVE: | ||||
| doMouseMove (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam)); | |||||
| doMouseMove (getPointFromLParam (lParam)); | |||||
| return 0; | return 0; | ||||
| case WM_MOUSELEAVE: | case WM_MOUSELEAVE: | ||||
| @@ -1833,13 +1742,13 @@ private: | |||||
| case WM_LBUTTONDOWN: | case WM_LBUTTONDOWN: | ||||
| case WM_MBUTTONDOWN: | case WM_MBUTTONDOWN: | ||||
| case WM_RBUTTONDOWN: | case WM_RBUTTONDOWN: | ||||
| doMouseDown (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam), wParam); | |||||
| doMouseDown (getPointFromLParam (lParam), wParam); | |||||
| return 0; | return 0; | ||||
| case WM_LBUTTONUP: | case WM_LBUTTONUP: | ||||
| case WM_MBUTTONUP: | case WM_MBUTTONUP: | ||||
| case WM_RBUTTONUP: | case WM_RBUTTONUP: | ||||
| doMouseUp (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam), wParam); | |||||
| doMouseUp (getPointFromLParam (lParam), wParam); | |||||
| return 0; | return 0; | ||||
| case WM_CAPTURECHANGED: | case WM_CAPTURECHANGED: | ||||
| @@ -1853,11 +1762,11 @@ private: | |||||
| return 0; | return 0; | ||||
| case 0x020A: /* WM_MOUSEWHEEL */ | case 0x020A: /* WM_MOUSEWHEEL */ | ||||
| doMouseWheel (wParam, true); | |||||
| doMouseWheel (getCurrentMousePos(), wParam, true); | |||||
| return 0; | return 0; | ||||
| case 0x020E: /* WM_MOUSEHWHEEL */ | case 0x020E: /* WM_MOUSEHWHEEL */ | ||||
| doMouseWheel (wParam, false); | |||||
| doMouseWheel (getCurrentMousePos(), wParam, false); | |||||
| return 0; | return 0; | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -1967,7 +1876,7 @@ private: | |||||
| component->repaint(); | component->repaint(); | ||||
| handleMovedOrResized(); | handleMovedOrResized(); | ||||
| if (! isValidMessageListener()) | |||||
| if (! ComponentPeer::isValidPeer (this)) | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -2042,31 +1951,31 @@ private: | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| const int oldModifiers = currentModifiers; | |||||
| MouseEvent e (Point<int>(), ModifierKeys::getCurrentModifiersRealtime(), component, | |||||
| getMouseEventTime(), Point<int>(), getMouseEventTime(), 1, false); | |||||
| ModifierKeys eventMods (ModifierKeys::getCurrentModifiersRealtime()); | |||||
| if (lParam == WM_LBUTTONDOWN || lParam == WM_LBUTTONDBLCLK) | if (lParam == WM_LBUTTONDOWN || lParam == WM_LBUTTONDBLCLK) | ||||
| e.mods = ModifierKeys (e.mods.getRawFlags() | ModifierKeys::leftButtonModifier); | |||||
| eventMods = eventMods.withFlags (ModifierKeys::leftButtonModifier); | |||||
| else if (lParam == WM_RBUTTONDOWN || lParam == WM_RBUTTONDBLCLK) | else if (lParam == WM_RBUTTONDOWN || lParam == WM_RBUTTONDBLCLK) | ||||
| e.mods = ModifierKeys (e.mods.getRawFlags() | ModifierKeys::rightButtonModifier); | |||||
| eventMods = eventMods.withFlags (ModifierKeys::rightButtonModifier); | |||||
| else if (lParam == WM_LBUTTONUP || lParam == WM_RBUTTONUP) | |||||
| eventMods = eventMods.withoutMouseButtons(); | |||||
| const MouseEvent e (Desktop::getInstance().getMainMouseSource(), | |||||
| Point<int>(), eventMods, component, getMouseEventTime(), | |||||
| Point<int>(), getMouseEventTime(), 1, false); | |||||
| if (lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN) | if (lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN) | ||||
| { | { | ||||
| SetFocus (hwnd); | SetFocus (hwnd); | ||||
| SetForegroundWindow (hwnd); | SetForegroundWindow (hwnd); | ||||
| component->mouseDown (e); | component->mouseDown (e); | ||||
| } | } | ||||
| else if (lParam == WM_LBUTTONUP || lParam == WM_RBUTTONUP) | else if (lParam == WM_LBUTTONUP || lParam == WM_RBUTTONUP) | ||||
| { | { | ||||
| e.mods = ModifierKeys (oldModifiers); | |||||
| component->mouseUp (e); | component->mouseUp (e); | ||||
| } | } | ||||
| else if (lParam == WM_LBUTTONDBLCLK || lParam == WM_LBUTTONDBLCLK) | else if (lParam == WM_LBUTTONDBLCLK || lParam == WM_LBUTTONDBLCLK) | ||||
| { | { | ||||
| e.mods = ModifierKeys (oldModifiers); | |||||
| component->mouseDoubleClick (e); | component->mouseDoubleClick (e); | ||||
| } | } | ||||
| else if (lParam == WM_MOUSEMOVE) | else if (lParam == WM_MOUSEMOVE) | ||||
| @@ -2216,6 +2125,9 @@ private: | |||||
| Win32ComponentPeer& operator= (const Win32ComponentPeer&); | Win32ComponentPeer& operator= (const Win32ComponentPeer&); | ||||
| }; | }; | ||||
| ModifierKeys Win32ComponentPeer::currentModifiers; | |||||
| ModifierKeys Win32ComponentPeer::modifiersAtLastCallback; | |||||
| ComponentPeer* Component::createNewPeer (int styleFlags, void* /*nativeWindowToAttachTo*/) | ComponentPeer* Component::createNewPeer (int styleFlags, void* /*nativeWindowToAttachTo*/) | ||||
| { | { | ||||
| return new Win32ComponentPeer (this, styleFlags); | return new Win32ComponentPeer (this, styleFlags); | ||||
| @@ -2223,6 +2135,28 @@ ComponentPeer* Component::createNewPeer (int styleFlags, void* /*nativeWindowToA | |||||
| juce_ImplementSingleton_SingleThreaded (Win32ComponentPeer::WindowClassHolder); | juce_ImplementSingleton_SingleThreaded (Win32ComponentPeer::WindowClassHolder); | ||||
| //============================================================================== | |||||
| void ModifierKeys::updateCurrentModifiers() throw() | |||||
| { | |||||
| currentModifiers = Win32ComponentPeer::currentModifiers; | |||||
| } | |||||
| const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() throw() | |||||
| { | |||||
| Win32ComponentPeer::updateKeyModifiers(); | |||||
| int keyMods = 0; | |||||
| if ((GetKeyState (VK_LBUTTON) & 0x8000) != 0) keyMods |= ModifierKeys::leftButtonModifier; | |||||
| if ((GetKeyState (VK_RBUTTON) & 0x8000) != 0) keyMods |= ModifierKeys::rightButtonModifier; | |||||
| if ((GetKeyState (VK_MBUTTON) & 0x8000) != 0) keyMods |= ModifierKeys::middleButtonModifier; | |||||
| Win32ComponentPeer::currentModifiers | |||||
| = Win32ComponentPeer::currentModifiers.withOnlyMouseButtons().withFlags (keyMods); | |||||
| return Win32ComponentPeer::currentModifiers; | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| void SystemTrayIconComponent::setIconImage (const Image& newImage) | void SystemTrayIconComponent::setIconImage (const Image& newImage) | ||||
| { | { | ||||