| @@ -288,6 +288,7 @@ | |||
| #include "../src/gui/components/mouse/juce_DragAndDropContainer.cpp" | |||
| #include "../src/gui/components/mouse/juce_MouseCursor.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_MouseListener.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 */; }; | |||
| 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 */; }; | |||
| 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 */; }; | |||
| 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 */; }; | |||
| @@ -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; }; | |||
| 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>"; }; | |||
| 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; }; | |||
| 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>"; }; | |||
| @@ -2674,6 +2678,8 @@ | |||
| 84F1EAD810403709006A1807 /* juce_MouseEvent.cpp */, | |||
| 84F1EAD910403709006A1807 /* juce_MouseHoverDetector.h */, | |||
| 84F1EADA10403709006A1807 /* juce_MouseHoverDetector.cpp */, | |||
| 84751E591132EE9E00640F9A /* juce_MouseInputSource.cpp */, | |||
| 84751E5A1132EE9E00640F9A /* juce_MouseInputSource.h */, | |||
| 84F1EADB10403709006A1807 /* juce_MouseListener.h */, | |||
| 84F1EADC10403709006A1807 /* juce_MouseListener.cpp */, | |||
| 84F1EADD10403709006A1807 /* juce_TooltipClient.h */, | |||
| @@ -3584,6 +3590,7 @@ | |||
| 8414DE8511122A8D00DAF75A /* juce_DynamicObject.h in Headers */, | |||
| 8473E64A11249FD800D74E02 /* juce_TextInputTarget.h in Headers */, | |||
| 8473E6531125974600D74E02 /* juce_Range.h in Headers */, | |||
| 84751E5C1132EE9E00640F9A /* juce_MouseInputSource.h in Headers */, | |||
| ); | |||
| runOnlyForDeploymentPostprocessing = 0; | |||
| }; | |||
| @@ -4226,6 +4233,7 @@ | |||
| 84CABF691101292D0088D64D /* juce_TemporaryFile.cpp in Sources */, | |||
| 8414DE78111229B300DAF75A /* juce_NamedValueSet.cpp in Sources */, | |||
| 8414DE8411122A8D00DAF75A /* juce_DynamicObject.cpp in Sources */, | |||
| 84751E5B1132EE9E00640F9A /* juce_MouseInputSource.cpp in Sources */, | |||
| ); | |||
| runOnlyForDeploymentPostprocessing = 0; | |||
| }; | |||
| @@ -1931,6 +1931,14 @@ | |||
| RelativePath="..\..\..\src\gui\components\mouse\juce_MouseHoverDetector.h" | |||
| > | |||
| </File> | |||
| <File | |||
| RelativePath="..\..\..\src\gui\components\mouse\juce_MouseInputSource.cpp" | |||
| > | |||
| </File> | |||
| <File | |||
| RelativePath="..\..\..\src\gui\components\mouse\juce_MouseInputSource.h" | |||
| > | |||
| </File> | |||
| <File | |||
| RelativePath="..\..\..\src\gui\components\mouse\juce_MouseListener.cpp" | |||
| > | |||
| @@ -43,7 +43,7 @@ | |||
| #define JUCE_MAJOR_VERSION 1 | |||
| #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) | |||
| @@ -1385,41 +1385,41 @@ private: | |||
| 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> | |||
| 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(); | |||
| } | |||
| OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const String& text); | |||
| OutputStream& operator<< (OutputStream& stream, const String& text); | |||
| #endif // __JUCE_STRING_JUCEHEADER__ | |||
| /*** End of inlined file: juce_String.h ***/ | |||
| @@ -2850,13 +2850,13 @@ public: | |||
| 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__ | |||
| /*** End of inlined file: juce_OutputStream.h ***/ | |||
| @@ -2913,9 +2913,6 @@ public: | |||
| bool isObject() const throw() { return type == objectType; } | |||
| 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; | |||
| static const var readFromStream (InputStream& input); | |||
| @@ -2956,6 +2953,8 @@ public: | |||
| juce_UseDebuggingNewOperator | |||
| bool equals (const var& other) const throw(); | |||
| private: | |||
| enum Type | |||
| { | |||
| @@ -2982,6 +2981,11 @@ private: | |||
| 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__ | |||
| /*** End of inlined file: juce_Variant.h ***/ | |||
| @@ -8924,12 +8928,42 @@ private: | |||
| #ifndef __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 ***/ | |||
| #ifndef __JUCE_MOUSEEVENT_JUCEHEADER__ | |||
| #define __JUCE_MOUSEEVENT_JUCEHEADER__ | |||
| class Component; | |||
| class MouseInputSource; | |||
| /*** Start of inlined file: juce_ModifierKeys.h ***/ | |||
| #ifndef __JUCE_MODIFIERKEYS_JUCEHEADER__ | |||
| @@ -8994,8 +9028,18 @@ public: | |||
| 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 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; } | |||
| int getNumMouseButtonsDown() const throw(); | |||
| @@ -9008,9 +9052,11 @@ private: | |||
| int flags; | |||
| static int currentModifierFlags; | |||
| static ModifierKeys currentModifiers; | |||
| friend class ComponentPeer; | |||
| friend class MouseInputSource; | |||
| friend class MouseInputSourceInternal; | |||
| static void updateCurrentModifiers() throw(); | |||
| }; | |||
| @@ -9163,7 +9209,8 @@ class JUCE_API MouseEvent | |||
| { | |||
| public: | |||
| MouseEvent (const Point<int>& position, | |||
| MouseEvent (MouseInputSource& source, | |||
| const Point<int>& position, | |||
| const ModifierKeys& modifiers, | |||
| Component* const originator, | |||
| const Time& eventTime, | |||
| @@ -9174,17 +9221,19 @@ public: | |||
| ~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(); | |||
| @@ -9220,6 +9269,8 @@ public: | |||
| 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 int getDoubleClickTimeout() throw(); | |||
| @@ -9227,42 +9278,17 @@ public: | |||
| juce_UseDebuggingNewOperator | |||
| 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__ | |||
| /*** 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 ***/ | |||
| #ifndef __JUCE_COMPONENTLISTENER_JUCEHEADER__ | |||
| @@ -11966,7 +11992,7 @@ public: | |||
| class ComponentBoundsConstrainer; | |||
| class ComponentDeletionWatcher; | |||
| class JUCE_API ComponentPeer : public MessageListener | |||
| class JUCE_API ComponentPeer | |||
| { | |||
| public: | |||
| @@ -12047,7 +12073,7 @@ public: | |||
| 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; | |||
| @@ -12089,15 +12115,8 @@ public: | |||
| 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(); | |||
| @@ -12133,8 +12152,6 @@ protected: | |||
| static void updateCurrentModifiers() throw(); | |||
| void handleMessage (const Message& message); | |||
| private: | |||
| Component* lastFocusedComponent; | |||
| @@ -12155,6 +12172,8 @@ private: | |||
| /*** End of inlined file: juce_ComponentPeer.h ***/ | |||
| class LookAndFeel; | |||
| class MouseInputSource; | |||
| class MouseInputSourceInternal; | |||
| class JUCE_API Component : public MouseListener, | |||
| protected MessageListener | |||
| @@ -12545,6 +12564,8 @@ private: | |||
| friend class ComponentPeer; | |||
| friend class InternalDragRepeater; | |||
| friend class MouseInputSource; | |||
| friend class MouseInputSourceInternal; | |||
| static Component* currentlyFocusedComponent; | |||
| static Component* componentUnderMouse; | |||
| @@ -12595,13 +12616,13 @@ private: | |||
| 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 internalFocusGain (const FocusChangeType cause); | |||
| void internalFocusLoss (const FocusChangeType cause); | |||
| @@ -12998,6 +13019,10 @@ private: | |||
| #endif // __JUCE_TIMER_JUCEHEADER__ | |||
| /*** End of inlined file: juce_Timer.h ***/ | |||
| class MouseInputSource; | |||
| class MouseInputSourceInternal; | |||
| class MouseListener; | |||
| class JUCE_API FocusChangeListener | |||
| { | |||
| public: | |||
| @@ -13057,12 +13082,18 @@ public: | |||
| 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: | |||
| static Desktop* instance; | |||
| friend class Component; | |||
| friend class ComponentPeer; | |||
| friend class MouseInputSource; | |||
| friend class MouseInputSourceInternal; | |||
| SortedSet <void*> mouseListeners, focusListeners; | |||
| Array <Component*> desktopComponents; | |||
| @@ -13073,24 +13104,12 @@ private: | |||
| Array <Rectangle<int> > monitorCoordsClipped, monitorCoordsUnclipped; | |||
| OwnedArray <MouseInputSource> mouseSources; | |||
| Point<int> lastFakeMouseMove; | |||
| int mouseClickCounter; | |||
| bool mouseMovedSignificantlySincePressed; | |||
| struct RecentMouseDown | |||
| { | |||
| Point<int> position; | |||
| int64 time; | |||
| Component* component; | |||
| }; | |||
| RecentMouseDown mouseDowns[4]; | |||
| 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; | |||
| Rectangle<int> kioskComponentOriginalBounds; | |||
| @@ -25899,6 +25918,7 @@ public: | |||
| juce_UseDebuggingNewOperator | |||
| private: | |||
| class ActiveXControlData; | |||
| friend class ActiveXControlData; | |||
| void* control; | |||
| bool mouseEventsAllowed; | |||
| @@ -26176,6 +26196,69 @@ private: | |||
| #ifndef __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 | |||
| { | |||
| public: | |||
| @@ -26204,6 +26287,7 @@ private: | |||
| ComponentPeer* peer; | |||
| bool deleteContent; | |||
| Graphics::ResamplingQuality quality; | |||
| MouseInputSource mouseSource; | |||
| void paint (Graphics& g); | |||
| void mouseDown (const MouseEvent& e); | |||
| @@ -26214,6 +26298,7 @@ private: | |||
| void mouseExit (const MouseEvent& e); | |||
| void mouseWheelMove (const MouseEvent& e, float, float); | |||
| void passOnMouseEventToPeer (const MouseEvent& e); | |||
| int scaleInt (const int n) const; | |||
| MagnifierComponent (const MagnifierComponent&); | |||
| @@ -169,7 +169,7 @@ public: | |||
| /** Returns true if this var has the same value as the one supplied. */ | |||
| bool equals (const var& other) const throw(); | |||
| private: | |||
| enum Type | |||
| { | |||
| @@ -33,7 +33,7 @@ | |||
| */ | |||
| #define JUCE_MAJOR_VERSION 1 | |||
| #define JUCE_MINOR_VERSION 51 | |||
| #define JUCE_BUILDNUMBER 2 | |||
| #define JUCE_BUILDNUMBER 3 | |||
| /** Current Juce version number. | |||
| @@ -1148,35 +1148,32 @@ void Slider::restoreMouseIfHidden() | |||
| : ((sliderBeingDragged == 1) ? getMinValue() | |||
| : (double) currentValue.getValue()); | |||
| Point<int> mousePos; | |||
| if (style == RotaryHorizontalDrag || style == RotaryVerticalDrag) | |||
| { | |||
| Point<int> mousePos (Desktop::getMousePosition()); | |||
| const Point<int> lastMouseDown (Desktop::getLastMouseDownPosition()); | |||
| mousePos = Desktop::getLastMouseDownPosition(); | |||
| if (style == RotaryHorizontalDrag) | |||
| { | |||
| 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 | |||
| { | |||
| 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 | |||
| { | |||
| 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 | |||
| 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); | |||
| 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_Timer.h" | |||
| #include "../../core/juce_Time.h" | |||
| #include "../../core/juce_Singleton.h" | |||
| #include "../../core/juce_PlatformUtilities.h" | |||
| #include "mouse/juce_MouseInputSource.h" | |||
| //============================================================================== | |||
| Component* Component::componentUnderMouse = 0; | |||
| @@ -1084,7 +1085,7 @@ bool Component::contains (const int x, const int y) | |||
| const ComponentPeer* const peer = getPeer(); | |||
| 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()) | |||
| { | |||
| @@ -2256,13 +2257,9 @@ void Component::internalMouseEnter (int x, int y, int64 time) | |||
| if (flags.repaintOnMouseActivityFlag) | |||
| 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); | |||
| @@ -2318,13 +2315,13 @@ void Component::internalMouseEnter (int x, int y, int64 time) | |||
| 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); | |||
| if (flags.draggingFlag) | |||
| { | |||
| internalMouseUp (ModifierKeys::getCurrentModifiers().getRawFlags(), x, y, time); | |||
| internalMouseUp (source, relativePos, time, source.getCurrentModifiers().getRawFlags()); | |||
| if (deletionChecker.hasBeenDeleted()) | |||
| return; | |||
| @@ -2341,13 +2338,9 @@ void Component::internalMouseExit (int x, int y, int64 time) | |||
| if (flags.repaintOnMouseActivityFlag) | |||
| 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); | |||
| if (deletionChecker.hasBeenDeleted()) | |||
| @@ -2403,23 +2396,33 @@ void Component::internalMouseExit (int x, int y, int64 time) | |||
| class InternalDragRepeater : public Timer | |||
| { | |||
| public: | |||
| InternalDragRepeater() {} | |||
| ~InternalDragRepeater() {} | |||
| InternalDragRepeater() | |||
| {} | |||
| ~InternalDragRepeater() | |||
| { | |||
| clearSingletonInstance(); | |||
| } | |||
| juce_DeclareSingleton_SingleThreaded_Minimal (InternalDragRepeater) | |||
| 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 | |||
| @@ -2429,31 +2432,27 @@ private: | |||
| InternalDragRepeater& operator= (const InternalDragRepeater&); | |||
| }; | |||
| static InternalDragRepeater* dragRepeater = 0; | |||
| juce_ImplementSingleton_SingleThreaded (InternalDragRepeater) | |||
| void Component::beginDragAutoRepeat (const int interval) | |||
| { | |||
| 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 | |||
| { | |||
| 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.registerMouseDown (relativePositionToGlobal (Point<int> (x, y)), time, this); | |||
| const ComponentDeletionWatcher deletionChecker (this); | |||
| if (isCurrentlyBlockedByAnotherModalComponent()) | |||
| @@ -2468,14 +2467,9 @@ void Component::internalMouseDown (const int x, const int y, const int64 time) | |||
| if (isCurrentlyBlockedByAnotherModalComponent()) | |||
| { | |||
| // 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(); | |||
| @@ -2521,14 +2515,9 @@ void Component::internalMouseDown (const int x, const int y, const int64 time) | |||
| if (flags.repaintOnMouseActivityFlag) | |||
| 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); | |||
| 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) | |||
| { | |||
| Desktop& desktop = Desktop::getInstance(); | |||
| flags.draggingFlag = false; | |||
| deleteAndZero (dragRepeater); | |||
| x += unboundedMouseOffset.getX(); | |||
| y += unboundedMouseOffset.getY(); | |||
| desktop.registerMouseDrag (relativePositionToGlobal (Point<int> (x, y))); | |||
| const ComponentDeletionWatcher deletionChecker (this); | |||
| if (flags.repaintOnMouseActivityFlag) | |||
| 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); | |||
| @@ -2719,33 +2696,22 @@ void Component::internalMouseUp (const int oldModifiers, int x, int y, const int | |||
| 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) | |||
| { | |||
| 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 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); | |||
| @@ -2800,8 +2766,8 @@ void Component::internalMouseDrag (int x, int y, const int64 time) | |||
| { | |||
| 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)) | |||
| { | |||
| @@ -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); | |||
| @@ -2841,13 +2807,9 @@ void Component::internalMouseMove (const int x, const int y, const int64 time) | |||
| { | |||
| 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()) | |||
| { | |||
| @@ -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(); | |||
| 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()) | |||
| { | |||
| @@ -2992,17 +2948,12 @@ void Component::internalMouseWheel (const int intAmountX, const int intAmountY, | |||
| p = p->parentComponent_; | |||
| } | |||
| sendFakeMouseMove(); | |||
| } | |||
| } | |||
| void Component::sendFakeMouseMove() const | |||
| { | |||
| ComponentPeer* const peer = getPeer(); | |||
| if (peer != 0) | |||
| peer->sendFakeMouseMove(); | |||
| Desktop::getInstance().getMainMouseSource().triggerFakeMove(); | |||
| } | |||
| void Component::broughtToFront() | |||
| @@ -28,6 +28,7 @@ | |||
| #include "mouse/juce_MouseCursor.h" | |||
| #include "mouse/juce_MouseListener.h" | |||
| #include "mouse/juce_MouseEvent.h" | |||
| #include "juce_ComponentListener.h" | |||
| #include "keyboard/juce_KeyListener.h" | |||
| #include "keyboard/juce_KeyboardFocusTraverser.h" | |||
| @@ -40,6 +41,8 @@ | |||
| #include "../../containers/juce_VoidArray.h" | |||
| #include "../../containers/juce_NamedValueSet.h" | |||
| class LookAndFeel; | |||
| class MouseInputSource; | |||
| class MouseInputSourceInternal; | |||
| //============================================================================== | |||
| @@ -1921,6 +1924,8 @@ private: | |||
| //============================================================================== | |||
| friend class ComponentPeer; | |||
| friend class InternalDragRepeater; | |||
| friend class MouseInputSource; | |||
| friend class MouseInputSourceInternal; | |||
| static Component* currentlyFocusedComponent; | |||
| 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 internalFocusGain (const FocusChangeType cause); | |||
| void internalFocusLoss (const FocusChangeType cause); | |||
| @@ -30,15 +30,20 @@ BEGIN_JUCE_NAMESPACE | |||
| #include "juce_Desktop.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() | |||
| : mouseClickCounter (0), | |||
| mouseMovedSignificantlySincePressed (false), | |||
| kioskModeComponent (0) | |||
| { | |||
| zerostruct (mouseDowns); | |||
| const int maxNumMice = 1; | |||
| for (int i = maxNumMice; --i >= 0;) | |||
| mouseSources.add (new MouseInputSource (i, true)); | |||
| refreshMonitorSizes(); | |||
| } | |||
| @@ -204,7 +209,7 @@ void Desktop::componentBroughtToFront (Component* const c) throw() | |||
| //============================================================================== | |||
| const Point<int> Desktop::getLastMouseDownPosition() throw() | |||
| { | |||
| return getInstance().mouseDowns[0].position; | |||
| return getInstance().getMainMouseSource().getLastMouseDownPosition(); | |||
| } | |||
| int Desktop::getMouseButtonClickCounter() throw() | |||
| @@ -217,59 +222,6 @@ void Desktop::incrementMouseClickCounter() throw() | |||
| ++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() | |||
| { | |||
| @@ -339,7 +291,7 @@ void Desktop::sendMouseMove() | |||
| const Point<int> pos (target->globalPositionToRelative (lastFakeMouseMove)); | |||
| const Time now (Time::getCurrentTime()); | |||
| const MouseEvent me (pos, ModifierKeys::getCurrentModifiers(), | |||
| const MouseEvent me (getMainMouseSource(), pos, ModifierKeys::getCurrentModifiers(), | |||
| target, now, pos, now, 0, false); | |||
| for (int i = mouseListeners.size(); --i >= 0;) | |||
| @@ -27,10 +27,16 @@ | |||
| #define __JUCE_DESKTOP_JUCEHEADER__ | |||
| #include "juce_Component.h" | |||
| #include "../../core/juce_Time.h" | |||
| #include "../../utilities/juce_DeletedAtShutdown.h" | |||
| #include "../../events/juce_Timer.h" | |||
| #include "../../events/juce_AsyncUpdater.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 */ | |||
| 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: | |||
| //============================================================================== | |||
| @@ -240,6 +249,8 @@ private: | |||
| friend class Component; | |||
| friend class ComponentPeer; | |||
| friend class MouseInputSource; | |||
| friend class MouseInputSourceInternal; | |||
| SortedSet <void*> mouseListeners, focusListeners; | |||
| Array <Component*> desktopComponents; | |||
| @@ -250,24 +261,12 @@ private: | |||
| Array <Rectangle<int> > monitorCoordsClipped, monitorCoordsUnclipped; | |||
| OwnedArray <MouseInputSource> mouseSources; | |||
| Point<int> lastFakeMouseMove; | |||
| int mouseClickCounter; | |||
| bool mouseMovedSignificantlySincePressed; | |||
| struct RecentMouseDown | |||
| { | |||
| Point<int> position; | |||
| int64 time; | |||
| Component* component; | |||
| }; | |||
| RecentMouseDown mouseDowns[4]; | |||
| 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; | |||
| Rectangle<int> kioskComponentOriginalBounds; | |||
| @@ -47,11 +47,11 @@ ModifierKeys& ModifierKeys::operator= (const ModifierKeys& other) throw() | |||
| return *this; | |||
| } | |||
| int ModifierKeys::currentModifierFlags = 0; | |||
| ModifierKeys ModifierKeys::currentModifiers; | |||
| const ModifierKeys ModifierKeys::getCurrentModifiers() throw() | |||
| { | |||
| return ModifierKeys (currentModifierFlags); | |||
| return currentModifiers; | |||
| } | |||
| int ModifierKeys::getNumMouseButtonsDown() const throw() | |||
| @@ -151,11 +151,23 @@ public: | |||
| 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. */ | |||
| 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. */ | |||
| inline bool testFlags (const int flagsToTest) const throw() { return (flags & flagsToTest) != 0; } | |||
| @@ -187,9 +199,11 @@ private: | |||
| //============================================================================== | |||
| int flags; | |||
| static int currentModifierFlags; | |||
| static ModifierKeys currentModifiers; | |||
| friend class ComponentPeer; | |||
| friend class MouseInputSource; | |||
| friend class MouseInputSourceInternal; | |||
| 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_, | |||
| Component* const originator, | |||
| const Time& eventTime_, | |||
| @@ -46,6 +47,7 @@ MouseEvent::MouseEvent (const Point<int>& position, | |||
| eventComponent (originator), | |||
| originalComponent (originator), | |||
| eventTime (eventTime_), | |||
| source (source_), | |||
| mouseDownPos (mouseDownPos_), | |||
| mouseDownTime (mouseDownTime_), | |||
| 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() | |||
| { | |||
| @@ -90,8 +114,7 @@ int MouseEvent::getDistanceFromDragStartY() const throw() | |||
| int MouseEvent::getDistanceFromDragStart() const throw() | |||
| { | |||
| return roundToInt (juce_hypot (getDistanceFromDragStartX(), | |||
| getDistanceFromDragStartY())); | |||
| return mouseDownPos.getDistanceFrom (getPosition()); | |||
| } | |||
| int MouseEvent::getLengthOfMousePress() const throw() | |||
| @@ -138,25 +161,6 @@ const Point<int> MouseEvent::getMouseDownScreenPosition() const | |||
| 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; | |||
| @@ -27,6 +27,7 @@ | |||
| #define __JUCE_MOUSEEVENT_JUCEHEADER__ | |||
| class Component; | |||
| class MouseInputSource; | |||
| #include "../keyboard/juce_ModifierKeys.h" | |||
| #include "../../../core/juce_Time.h" | |||
| #include "../../graphics/geometry/juce_Point.h" | |||
| @@ -47,6 +48,7 @@ public: | |||
| 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 modifiers the key modifiers at the time of the event | |||
| @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 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, | |||
| Component* const originator, | |||
| const Time& eventTime, | |||
| @@ -78,14 +81,14 @@ public: | |||
| This value is relative to the top-left of the component to which the | |||
| event applies (as indicated by the MouseEvent::eventComponent field). | |||
| */ | |||
| int x; | |||
| const int x; | |||
| /** The y-position of the mouse when the event occurred. | |||
| This value is relative to the top-left of the component to which the | |||
| event applies (as indicated by the MouseEvent::eventComponent field). | |||
| */ | |||
| int y; | |||
| const int y; | |||
| /** 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 | |||
| 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. | |||
| @@ -110,7 +113,7 @@ public: | |||
| @see originalComponent | |||
| */ | |||
| Component* eventComponent; | |||
| Component* const eventComponent; | |||
| /** The component that the event first occurred on. | |||
| @@ -119,11 +122,15 @@ public: | |||
| @see eventComponent | |||
| */ | |||
| Component* originalComponent; | |||
| Component* const originalComponent; | |||
| /** 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. | |||
| @@ -218,7 +225,7 @@ public: | |||
| The co-ordinates are relative to the top-left of the main monitor. | |||
| @see getMouseDownScreenX, Desktop::getMousePosition | |||
| @see getScreenPosition | |||
| */ | |||
| int getScreenX() const; | |||
| @@ -226,7 +233,7 @@ public: | |||
| The co-ordinates are relative to the top-left of the main monitor. | |||
| @see getMouseDownScreenY, Desktop::getMousePosition | |||
| @see getScreenPosition | |||
| */ | |||
| int getScreenY() const; | |||
| @@ -234,7 +241,7 @@ public: | |||
| The co-ordinates are relative to the top-left of the main monitor. | |||
| @see getMouseDownScreenY, Desktop::getMousePosition | |||
| @see getMouseDownScreenPosition | |||
| */ | |||
| const Point<int> getScreenPosition() const; | |||
| @@ -242,7 +249,7 @@ public: | |||
| The co-ordinates are relative to the top-left of the main monitor. | |||
| @see getScreenX, Desktop::getMousePosition | |||
| @see getMouseDownScreenPosition | |||
| */ | |||
| int getMouseDownScreenX() const; | |||
| @@ -250,7 +257,7 @@ public: | |||
| The co-ordinates are relative to the top-left of the main monitor. | |||
| @see getScreenY, Desktop::getMousePosition | |||
| @see getMouseDownScreenPosition | |||
| */ | |||
| int getMouseDownScreenY() const; | |||
| @@ -258,7 +265,7 @@ public: | |||
| The co-ordinates are relative to the top-left of the main monitor. | |||
| @see getScreenY, Desktop::getMousePosition | |||
| @see getScreenPosition | |||
| */ | |||
| const Point<int> getMouseDownScreenPosition() const; | |||
| @@ -270,6 +277,12 @@ public: | |||
| */ | |||
| 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. | |||
| @@ -294,10 +307,12 @@ public: | |||
| juce_UseDebuggingNewOperator | |||
| 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_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__ | |||
| #define __JUCE_MOUSELISTENER_JUCEHEADER__ | |||
| #include "juce_MouseEvent.h" | |||
| class MouseEvent; | |||
| //============================================================================== | |||
| /** | |||
| @@ -116,6 +116,7 @@ public: | |||
| juce_UseDebuggingNewOperator | |||
| private: | |||
| class ActiveXControlData; | |||
| friend class ActiveXControlData; | |||
| void* control; | |||
| bool mouseEventsAllowed; | |||
| @@ -110,10 +110,10 @@ public: | |||
| 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) | |||
| @@ -193,7 +193,8 @@ MagnifierComponent::MagnifierComponent (Component* const content_, | |||
| scaleFactor (0.0), | |||
| peer (0), | |||
| deleteContent (deleteContentCompWhenNoLongerNeeded), | |||
| quality (Graphics::lowResamplingQuality) | |||
| quality (Graphics::lowResamplingQuality), | |||
| mouseSource (0, true) | |||
| { | |||
| holderComp = new PeerHolderComp (this); | |||
| setScaleFactor (1.0); | |||
| @@ -285,48 +286,48 @@ void MagnifierComponent::childBoundsChanged (Component* c) | |||
| roundToInt (c->getHeight() * scaleFactor)); | |||
| } | |||
| void MagnifierComponent::mouseDown (const MouseEvent& e) | |||
| void MagnifierComponent::passOnMouseEventToPeer (const MouseEvent& e) | |||
| { | |||
| 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) | |||
| { | |||
| 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) | |||
| { | |||
| if (peer != 0) | |||
| peer->handleMouseDrag (Point<int> (scaleInt (e.x), scaleInt (e.y)), e.eventTime.toMilliseconds()); | |||
| passOnMouseEventToPeer (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) | |||
| { | |||
| if (peer != 0) | |||
| peer->handleMouseEnter (Point<int> (scaleInt (e.x), scaleInt (e.y)), e.eventTime.toMilliseconds()); | |||
| passOnMouseEventToPeer (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) | |||
| { | |||
| 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 | |||
| Component::mouseWheelMove (e, ix, iy); | |||
| } | |||
| @@ -27,6 +27,7 @@ | |||
| #define __JUCE_MAGNIFIERCOMPONENT_JUCEHEADER__ | |||
| #include "../juce_Component.h" | |||
| #include "../mouse/juce_MouseInputSource.h" | |||
| //============================================================================== | |||
| @@ -100,6 +101,7 @@ private: | |||
| ComponentPeer* peer; | |||
| bool deleteContent; | |||
| Graphics::ResamplingQuality quality; | |||
| MouseInputSource mouseSource; | |||
| //============================================================================== | |||
| void paint (Graphics& g); | |||
| @@ -111,6 +113,7 @@ private: | |||
| void mouseExit (const MouseEvent& e); | |||
| void mouseWheelMove (const MouseEvent& e, float, float); | |||
| void passOnMouseEventToPeer (const MouseEvent& e); | |||
| int scaleInt (const int n) const; | |||
| MagnifierComponent (const MagnifierComponent&); | |||
| @@ -36,12 +36,12 @@ BEGIN_JUCE_NAMESPACE | |||
| #include "../../../core/juce_Random.h" | |||
| #include "../layout/juce_ComponentBoundsConstrainer.h" | |||
| #include "../mouse/juce_FileDragAndDropTarget.h" | |||
| #include "../mouse/juce_MouseInputSource.h" | |||
| //#define JUCE_ENABLE_REPAINT_DEBUGGING 1 | |||
| //============================================================================== | |||
| static const int fakeMouseMoveMessage = 0x7fff00ff; | |||
| 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 | |||
| */ | |||
| class JUCE_API ComponentPeer : public MessageListener | |||
| class JUCE_API ComponentPeer | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| @@ -197,7 +197,7 @@ public: | |||
| is false, then this returns false if the point is actually inside a child of this | |||
| 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. | |||
| @@ -295,16 +295,8 @@ public: | |||
| 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(); | |||
| @@ -373,9 +365,6 @@ protected: | |||
| static void updateCurrentModifiers() throw(); | |||
| /** @internal */ | |||
| void handleMessage (const Message& message); | |||
| private: | |||
| //============================================================================== | |||
| Component* lastFocusedComponent; | |||
| @@ -230,7 +230,7 @@ public: | |||
| 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 | |||
| : lookupTable [jlimit (0, numEntries, (x * scale - start) >> (int) numScaleBits)]; | |||
| @@ -274,7 +274,7 @@ public: | |||
| dy *= dy; | |||
| } | |||
| forcedinline const PixelARGB getPixel (const int px) const throw() | |||
| inline const PixelARGB getPixel (const int px) const throw() | |||
| { | |||
| double x = px - gx1; | |||
| x *= x; | |||
| @@ -312,7 +312,7 @@ public: | |||
| 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; | |||
| 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); | |||
| } | |||
| OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const double number) | |||
| OutputStream& operator<< (OutputStream& stream, const double 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); | |||
| 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)); | |||
| return stream; | |||
| @@ -207,16 +207,16 @@ public: | |||
| //============================================================================== | |||
| /** 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. */ | |||
| OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const double number); | |||
| OutputStream& operator<< (OutputStream& stream, const double number); | |||
| /** 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. */ | |||
| 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_QuickTimeMovieComponent.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/special/juce_NSViewComponent.h" | |||
| #include "../gui/components/layout/juce_ComponentMovementWatcher.h" | |||
| @@ -120,33 +120,6 @@ enum MouseButtons | |||
| 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 NumLockMask = 0; | |||
| @@ -200,124 +173,6 @@ bool KeyPress::isKeyCurrentlyDown (const int keyCode) throw() | |||
| 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 | |||
| static bool isShmAvailable() throw() | |||
| @@ -605,7 +460,6 @@ public: | |||
| wh (0), | |||
| taskbarImage (0), | |||
| fullScreen (false), | |||
| entered (false), | |||
| mapped (false) | |||
| { | |||
| // it's dangerous to create a window on a thread other than the message thread.. | |||
| @@ -644,7 +498,7 @@ public: | |||
| ScopedXLock xlock; | |||
| if (! XFindContext (display, (XID) windowHandle, improbableNumber, &peer)) | |||
| { | |||
| if (peer != 0 && ! ((LinuxComponentPeer*) peer)->isValidMessageListener()) | |||
| if (peer != 0 && ! ComponentPeer::isValidPeer ((LinuxComponentPeer*) peer)) | |||
| peer = 0; | |||
| } | |||
| @@ -854,9 +708,10 @@ public: | |||
| 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 | |||
| || ((unsigned int) y) >= (unsigned int) wh) | |||
| @@ -1166,10 +1021,9 @@ public: | |||
| int keyCode = (int) unicodeChar; | |||
| 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; | |||
| const bool keyDownChange = (sym != NoSymbol) && ! updateKeyModifiersFromSym (sym, true); | |||
| @@ -1267,7 +1121,7 @@ public: | |||
| ScopedXLock xlock; | |||
| KeySym sym = XKeycodeToKeysym (display, keyEvent->keycode, 0); | |||
| const int oldMods = currentModifiers; | |||
| const ModifierKeys oldMods (currentModifiers); | |||
| const bool keyDownChange = (sym != NoSymbol) && ! updateKeyModifiersFromSym (sym, false); | |||
| if (oldMods != currentModifiers) | |||
| @@ -1282,48 +1136,37 @@ public: | |||
| case ButtonPress: | |||
| { | |||
| const XButtonPressedEvent* const buttonPressEvent = (const XButtonPressedEvent*) &event->xbutton; | |||
| updateKeyModifiers (buttonPressEvent->state); | |||
| bool buttonMsg = false; | |||
| bool wheelUpMsg = false; | |||
| bool wheelDownMsg = false; | |||
| 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) | |||
| { | |||
| currentModifiers |= ModifierKeys::leftButtonModifier; | |||
| currentModifiers = currentModifiers.withFlags (ModifierKeys::leftButtonModifier); | |||
| buttonMsg = true; | |||
| } | |||
| else if (map == RightButton) | |||
| { | |||
| currentModifiers |= ModifierKeys::rightButtonModifier; | |||
| currentModifiers = currentModifiers.withFlags (ModifierKeys::rightButtonModifier); | |||
| buttonMsg = true; | |||
| } | |||
| else if (map == MiddleButton) | |||
| { | |||
| currentModifiers |= ModifierKeys::middleButtonModifier; | |||
| currentModifiers = currentModifiers.withFlags (ModifierKeys::middleButtonModifier); | |||
| buttonMsg = true; | |||
| } | |||
| else if (map == WheelUp) | |||
| { | |||
| wheelUpMsg = true; | |||
| } | |||
| else if (map == WheelDown) | |||
| { | |||
| wheelDownMsg = true; | |||
| } | |||
| updateKeyModifiers (buttonPressEvent->state); | |||
| if (buttonMsg) | |||
| { | |||
| 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)); | |||
| } | |||
| @@ -1334,22 +1177,19 @@ public: | |||
| case ButtonRelease: | |||
| { | |||
| const XButtonReleasedEvent* const buttonRelEvent = (const XButtonReleasedEvent*) &event->xbutton; | |||
| updateKeyModifiers (buttonRelEvent->state); | |||
| const int oldModifiers = currentModifiers; | |||
| const int map = pointerMap [buttonRelEvent->button - Button1]; | |||
| if (map == LeftButton) | |||
| currentModifiers &= ~ModifierKeys::leftButtonModifier; | |||
| currentModifiers = currentModifiers.withoutFlags (ModifierKeys::leftButtonModifier); | |||
| else if (map == RightButton) | |||
| currentModifiers &= ~ModifierKeys::rightButtonModifier; | |||
| currentModifiers = currentModifiers.withoutFlags (ModifierKeys::rightButtonModifier); | |||
| 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(); | |||
| break; | |||
| @@ -1358,10 +1198,9 @@ public: | |||
| case MotionNotify: | |||
| { | |||
| const XPointerMovedEvent* const movedEvent = (const XPointerMovedEvent*) &event->xmotion; | |||
| updateKeyModifiers (movedEvent->state); | |||
| Point<int> mousePos (Desktop::getMousePosition()); | |||
| const Point<int> mousePos (Desktop::getMousePosition()); | |||
| if (lastMousePos != mousePos) | |||
| { | |||
| @@ -1370,37 +1209,28 @@ public: | |||
| if (parentWindow != 0 && (styleFlags & windowHasTitleBar) == 0) | |||
| { | |||
| Window wRoot = 0, wParent = 0; | |||
| Window* wChild = 0; | |||
| unsigned int numChildren; | |||
| { | |||
| ScopedXLock xlock; | |||
| unsigned int numChildren; | |||
| Window* wChild = 0; | |||
| XQueryTree (display, windowH, &wRoot, &wParent, &wChild, &numChildren); | |||
| } | |||
| if (wParent != 0 | |||
| && wParent != windowH | |||
| && wParent != wRoot) | |||
| && wParent != windowH | |||
| && wParent != wRoot) | |||
| { | |||
| parentWindow = wParent; | |||
| updateBounds(); | |||
| mousePos -= getScreenPosition(); | |||
| } | |||
| else | |||
| { | |||
| 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; | |||
| @@ -1411,14 +1241,10 @@ public: | |||
| clearLastMousePos(); | |||
| const XEnterWindowEvent* const enterEvent = (const XEnterWindowEvent*) &event->xcrossing; | |||
| if ((currentModifiers & ModifierKeys::allMouseButtonModifiers) == 0 | |||
| && ! entered) | |||
| if (! currentModifiers.isAnyMouseButtonDown()) | |||
| { | |||
| 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; | |||
| @@ -1431,15 +1257,11 @@ public: | |||
| // 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 | |||
| // 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); | |||
| handleMouseExit (Point<int> (leaveEvent->x, leaveEvent->y), getEventTime (leaveEvent->time)); | |||
| entered = false; | |||
| handleMouseEvent (Point<int> (leaveEvent->x, leaveEvent->y), currentModifiers, getEventTime (leaveEvent->time)); | |||
| } | |||
| break; | |||
| @@ -1570,7 +1392,7 @@ public: | |||
| // Deal with modifier/keyboard mapping | |||
| ScopedXLock xlock; | |||
| XRefreshKeyboardMapping (mappingEvent); | |||
| getModifierMapping(); | |||
| updateModifierMappings(); | |||
| } | |||
| break; | |||
| @@ -1726,6 +1548,8 @@ public: | |||
| bool dontRepaint; | |||
| static ModifierKeys currentModifiers; | |||
| private: | |||
| //============================================================================== | |||
| class LinuxRepaintManager : public Timer | |||
| @@ -1870,7 +1694,7 @@ private: | |||
| Window windowH, parentWindow; | |||
| int wx, wy, ww, wh; | |||
| Image* taskbarImage; | |||
| bool fullScreen, entered, mapped, depthIs16Bit; | |||
| bool fullScreen, mapped, depthIs16Bit; | |||
| BorderSize windowBorder; | |||
| struct MotifWmHints | |||
| @@ -1882,6 +1706,100 @@ private: | |||
| 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) | |||
| { | |||
| @@ -2195,7 +2113,7 @@ private: | |||
| } | |||
| } | |||
| getModifierMapping(); | |||
| updateModifierMappings(); | |||
| } | |||
| windowH = wndH; | |||
| @@ -2220,7 +2138,7 @@ private: | |||
| {} | |||
| } | |||
| static int64 getEventTime (::Time t) throw() | |||
| static int64 getEventTime (::Time t) | |||
| { | |||
| static int64 eventTimeOffset = 0x12345678; | |||
| const int64 thisMessageTime = t; | |||
| @@ -2566,9 +2484,37 @@ private: | |||
| } | |||
| }; | |||
| ModifierKeys LinuxComponentPeer::currentModifiers; | |||
| int LinuxComponentPeer::pointerMap[5]; | |||
| 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) | |||
| @@ -2721,8 +2667,22 @@ bool Desktop::canUseSemiTransparentWindows() throw() | |||
| 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) | |||
| @@ -101,7 +101,7 @@ public: | |||
| bool isMinimised() const; | |||
| void setFullScreen (bool shouldBeFullScreen); | |||
| 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; | |||
| bool setAlwaysOnTop (bool alwaysOnTop); | |||
| void toFront (bool makeActiveWindow); | |||
| @@ -133,6 +133,7 @@ public: | |||
| UIWindow* window; | |||
| JuceUIView* view; | |||
| bool isSharedWindow, fullScreen, insideDrawRect; | |||
| static ModifierKeys currentModifiers; | |||
| }; | |||
| //============================================================================== | |||
| @@ -167,23 +168,16 @@ bool KeyPress::isKeyCurrentlyDown (const int keyCode) throw() | |||
| return false; | |||
| } | |||
| static int currentModifiers = 0; | |||
| ModifierKeys UIViewComponentPeer::currentModifiers; | |||
| const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() throw() | |||
| { | |||
| return ModifierKeys (currentModifiers); | |||
| return UIViewComponentPeer::currentModifiers; | |||
| } | |||
| 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) | |||
| @@ -208,13 +202,15 @@ JUCE_NAMESPACE::Point<int> juce_lastMousePos; | |||
| { | |||
| CGPoint p = [[t objectAtIndex: 0] locationInView: self]; | |||
| const JUCE_NAMESPACE::Point<int> pos ((int) p.x, (int) p.y); | |||
| currentModifiers |= getModifierForButtonNumber (0); | |||
| 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: | |||
| @@ -238,7 +234,7 @@ JUCE_NAMESPACE::Point<int> juce_lastMousePos; | |||
| const JUCE_NAMESPACE::Point<int> pos ((int) p.x, (int) p.y); | |||
| juce_lastMousePos = pos + owner->getScreenPosition(); | |||
| owner->handleMouseDrag (pos, getMouseTime (event)); | |||
| owner->handleMouseEvent (pos, JUCE_NAMESPACE::UIViewComponentPeer::currentModifiers, getMouseTime (event)); | |||
| } | |||
| default: | |||
| @@ -262,9 +258,10 @@ JUCE_NAMESPACE::Point<int> juce_lastMousePos; | |||
| const JUCE_NAMESPACE::Point<int> pos ((int) p.x, (int) p.y); | |||
| 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: | |||
| @@ -559,15 +556,15 @@ bool UIViewComponentPeer::isFullScreen() const | |||
| 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; | |||
| 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]; | |||
| @@ -159,7 +159,7 @@ public: | |||
| bool isMinimised() const; | |||
| void setFullScreen (bool shouldBeFullScreen); | |||
| 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; | |||
| bool setAlwaysOnTop (bool alwaysOnTop); | |||
| void toFront (bool makeActiveWindow); | |||
| @@ -186,6 +186,7 @@ public: | |||
| virtual void redirectMouseEnter (NSEvent* ev); | |||
| virtual void redirectMouseExit (NSEvent* ev); | |||
| virtual void redirectMouseWheel (NSEvent* ev); | |||
| void sendMouseEvent (NSEvent* ev); | |||
| bool handleKeyEvent (NSEvent* ev, bool isKeyDown); | |||
| virtual bool redirectKeyDown (NSEvent* ev); | |||
| @@ -261,6 +262,10 @@ public: | |||
| NSWindow* window; | |||
| JuceNSView* view; | |||
| 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 | |||
| //============================================================================== | |||
| static ComponentPeer* currentlyFocusedPeer = 0; | |||
| static VoidArray keysCurrentlyDown; | |||
| ModifierKeys NSViewComponentPeer::currentModifiers; | |||
| ComponentPeer* NSViewComponentPeer::currentlyFocusedPeer = 0; | |||
| VoidArray NSViewComponentPeer::keysCurrentlyDown; | |||
| //============================================================================== | |||
| bool KeyPress::isKeyCurrentlyDown (const int keyCode) throw() | |||
| { | |||
| if (keysCurrentlyDown.contains ((void*) keyCode)) | |||
| if (NSViewComponentPeer::keysCurrentlyDown.contains ((void*) keyCode)) | |||
| return true; | |||
| if (keyCode >= 'A' && keyCode <= 'Z' | |||
| && keysCurrentlyDown.contains ((void*) (int) CharacterFunctions::toLowerCase ((tchar) keyCode))) | |||
| && NSViewComponentPeer::keysCurrentlyDown.contains ((void*) (int) CharacterFunctions::toLowerCase ((tchar) keyCode))) | |||
| return true; | |||
| 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 false; | |||
| } | |||
| static int currentModifiers = 0; | |||
| 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) | |||
| @@ -805,12 +802,12 @@ void NSViewComponentPeer::updateKeysDown (NSEvent* ev, bool isKeyDown) | |||
| const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() throw() | |||
| { | |||
| return ModifierKeys (currentModifiers); | |||
| return NSViewComponentPeer::currentModifiers; | |||
| } | |||
| void ModifierKeys::updateCurrentModifiers() throw() | |||
| { | |||
| currentModifierFlags = currentModifiers; | |||
| currentModifiers = NSViewComponentPeer::currentModifiers; | |||
| } | |||
| //============================================================================== | |||
| @@ -1106,15 +1103,15 @@ bool NSViewComponentPeer::isFullScreen() const | |||
| 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; | |||
| 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]; | |||
| @@ -1226,19 +1223,19 @@ void NSViewComponentPeer::viewFocusLoss() | |||
| void juce_HandleProcessFocusChange() | |||
| { | |||
| keysCurrentlyDown.clear(); | |||
| NSViewComponentPeer::keysCurrentlyDown.clear(); | |||
| if (NSViewComponentPeer::isValidPeer (currentlyFocusedPeer)) | |||
| if (NSViewComponentPeer::isValidPeer (NSViewComponentPeer::currentlyFocusedPeer)) | |||
| { | |||
| if (Process::isForegroundProcess()) | |||
| { | |||
| currentlyFocusedPeer->handleFocusGain(); | |||
| NSViewComponentPeer::currentlyFocusedPeer->handleFocusGain(); | |||
| ComponentPeer::bringModalComponentToFront(); | |||
| } | |||
| else | |||
| { | |||
| currentlyFocusedPeer->handleFocusLoss(); | |||
| NSViewComponentPeer::currentlyFocusedPeer->handleFocusLoss(); | |||
| // turn kiosk mode off if we lose focus.. | |||
| Desktop::getInstance().setKioskModeComponent (0); | |||
| @@ -1355,55 +1352,56 @@ bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev) | |||
| #endif | |||
| //============================================================================== | |||
| void NSViewComponentPeer::redirectMouseDown (NSEvent* ev) | |||
| void NSViewComponentPeer::sendMouseEvent (NSEvent* 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) | |||
| { | |||
| 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(); | |||
| } | |||
| 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) | |||
| { | |||
| updateModifiers (ev); | |||
| handleMouseMove (getMousePos (ev, view), getMouseTime (ev)); | |||
| currentModifiers = currentModifiers.withoutMouseButtons(); | |||
| sendMouseEvent (ev); | |||
| showArrowCursorIfNeeded(); | |||
| } | |||
| void NSViewComponentPeer::redirectMouseEnter (NSEvent* ev) | |||
| { | |||
| updateModifiers (ev); | |||
| handleMouseEnter (getMousePos (ev, view), getMouseTime (ev)); | |||
| currentModifiers = currentModifiers.withoutMouseButtons(); | |||
| sendMouseEvent (ev); | |||
| } | |||
| void NSViewComponentPeer::redirectMouseExit (NSEvent* ev) | |||
| { | |||
| updateModifiers (ev); | |||
| handleMouseExit (getMousePos (ev, view), getMouseTime (ev)); | |||
| currentModifiers = currentModifiers.withoutMouseButtons(); | |||
| sendMouseEvent (ev); | |||
| } | |||
| void NSViewComponentPeer::redirectMouseWheel (NSEvent* 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() | |||
| @@ -27,223 +27,272 @@ | |||
| // compiled on its own). | |||
| #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; | |||
| } | |||
| *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; | |||
| bool wasShowing; | |||
| @@ -261,8 +310,8 @@ public: | |||
| owner (owner_), | |||
| wasShowing (owner_ != 0 && owner_->isShowing()), | |||
| controlHWND (0), | |||
| storage (new JuceIStorage()), | |||
| clientSite (new JuceIOleClientSite (hwnd)), | |||
| storage (new ActiveXHelpers::JuceIStorage()), | |||
| clientSite (new ActiveXHelpers::JuceIOleClientSite (hwnd)), | |||
| control (0) | |||
| { | |||
| } | |||
| @@ -315,124 +364,66 @@ public: | |||
| return ((ActiveXControlData*) ax->control) != 0 | |||
| && ((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() | |||
| : originalWndProc (0), | |||
| control (0), | |||
| mouseEventsAllowed (true) | |||
| { | |||
| activeXComps.add (this); | |||
| ActiveXHelpers::activeXComps.add (this); | |||
| } | |||
| ActiveXControlComponent::~ActiveXControlComponent() | |||
| { | |||
| deleteControl(); | |||
| activeXComps.removeValue (this); | |||
| ActiveXHelpers::activeXComps.removeValue (this); | |||
| } | |||
| void ActiveXControlComponent::paint (Graphics& g) | |||
| @@ -476,12 +467,12 @@ bool ActiveXControlComponent::createControl (const void* controlIID) | |||
| control = info.release(); | |||
| 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) | |||
| { | |||
| 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; | |||
| @@ -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() | |||
| { | |||
| SHORT k = (SHORT) keyCode; | |||
| @@ -389,39 +362,6 @@ bool KeyPress::isKeyCurrentlyDown (const int keyCode) throw() | |||
| 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) | |||
| { | |||
| if (MessageManager::getInstance()->currentThreadHasLockedMessageManager()) | |||
| @@ -666,17 +606,20 @@ public: | |||
| 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; | |||
| GetWindowRect (hwnd, &r); | |||
| 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); | |||
| return w == hwnd || (trueIfInAChildWindow && (IsChild (hwnd, w) != 0)); | |||
| } | |||
| @@ -849,11 +792,52 @@ public: | |||
| 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 | |||
| bool dontRepaint; | |||
| static ModifierKeys currentModifiers; | |||
| static ModifierKeys modifiersAtLastCallback; | |||
| private: | |||
| HWND hwnd; | |||
| 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) | |||
| { | |||
| isMouseOver = true; | |||
| updateKeyModifiers(); | |||
| TRACKMOUSEEVENT tme; | |||
| tme.cbSize = sizeof (tme); | |||
| @@ -1278,151 +1260,63 @@ private: | |||
| tme.dwHoverTime = 0; | |||
| if (! TrackMouseEvent (&tme)) | |||
| { | |||
| jassertfalse; | |||
| } | |||
| updateKeyModifiers(); | |||
| handleMouseEnter (Point<int> (x, y), mouseEventTime); | |||
| } | |||
| 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) | |||
| 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; | |||
| 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; | |||
| // 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(); | |||
| handleMouseUp (oldModifiers, Point<int> (x, y), getMouseEventTime()); | |||
| doMouseEvent (position); | |||
| } | |||
| void doCaptureChanged() | |||
| { | |||
| 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() | |||
| { | |||
| 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(); | |||
| 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; | |||
| // 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; | |||
| } | |||
| @@ -1784,6 +1678,21 @@ public: | |||
| } | |||
| 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) | |||
| { | |||
| if (isValidPeer (this)) | |||
| @@ -1823,7 +1732,7 @@ private: | |||
| //============================================================================== | |||
| case WM_MOUSEMOVE: | |||
| doMouseMove (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam)); | |||
| doMouseMove (getPointFromLParam (lParam)); | |||
| return 0; | |||
| case WM_MOUSELEAVE: | |||
| @@ -1833,13 +1742,13 @@ private: | |||
| case WM_LBUTTONDOWN: | |||
| case WM_MBUTTONDOWN: | |||
| case WM_RBUTTONDOWN: | |||
| doMouseDown (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam), wParam); | |||
| doMouseDown (getPointFromLParam (lParam), wParam); | |||
| return 0; | |||
| case WM_LBUTTONUP: | |||
| case WM_MBUTTONUP: | |||
| case WM_RBUTTONUP: | |||
| doMouseUp (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam), wParam); | |||
| doMouseUp (getPointFromLParam (lParam), wParam); | |||
| return 0; | |||
| case WM_CAPTURECHANGED: | |||
| @@ -1853,11 +1762,11 @@ private: | |||
| return 0; | |||
| case 0x020A: /* WM_MOUSEWHEEL */ | |||
| doMouseWheel (wParam, true); | |||
| doMouseWheel (getCurrentMousePos(), wParam, true); | |||
| return 0; | |||
| case 0x020E: /* WM_MOUSEHWHEEL */ | |||
| doMouseWheel (wParam, false); | |||
| doMouseWheel (getCurrentMousePos(), wParam, false); | |||
| return 0; | |||
| //============================================================================== | |||
| @@ -1967,7 +1876,7 @@ private: | |||
| component->repaint(); | |||
| handleMovedOrResized(); | |||
| if (! isValidMessageListener()) | |||
| if (! ComponentPeer::isValidPeer (this)) | |||
| return 0; | |||
| } | |||
| @@ -2042,31 +1951,31 @@ private: | |||
| } | |||
| 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) | |||
| e.mods = ModifierKeys (e.mods.getRawFlags() | ModifierKeys::leftButtonModifier); | |||
| eventMods = eventMods.withFlags (ModifierKeys::leftButtonModifier); | |||
| 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) | |||
| { | |||
| SetFocus (hwnd); | |||
| SetForegroundWindow (hwnd); | |||
| component->mouseDown (e); | |||
| } | |||
| else if (lParam == WM_LBUTTONUP || lParam == WM_RBUTTONUP) | |||
| { | |||
| e.mods = ModifierKeys (oldModifiers); | |||
| component->mouseUp (e); | |||
| } | |||
| else if (lParam == WM_LBUTTONDBLCLK || lParam == WM_LBUTTONDBLCLK) | |||
| { | |||
| e.mods = ModifierKeys (oldModifiers); | |||
| component->mouseDoubleClick (e); | |||
| } | |||
| else if (lParam == WM_MOUSEMOVE) | |||
| @@ -2216,6 +2125,9 @@ private: | |||
| Win32ComponentPeer& operator= (const Win32ComponentPeer&); | |||
| }; | |||
| ModifierKeys Win32ComponentPeer::currentModifiers; | |||
| ModifierKeys Win32ComponentPeer::modifiersAtLastCallback; | |||
| ComponentPeer* Component::createNewPeer (int styleFlags, void* /*nativeWindowToAttachTo*/) | |||
| { | |||
| return new Win32ComponentPeer (this, styleFlags); | |||
| @@ -2223,6 +2135,28 @@ ComponentPeer* Component::createNewPeer (int styleFlags, void* /*nativeWindowToA | |||
| 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) | |||
| { | |||