diff --git a/amalgamation/juce_amalgamated_template.cpp b/amalgamation/juce_amalgamated_template.cpp index 499cc6d9ba..cf47f13111 100644 --- a/amalgamation/juce_amalgamated_template.cpp +++ b/amalgamation/juce_amalgamated_template.cpp @@ -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" diff --git a/build/macosx/Juce.xcodeproj/project.pbxproj b/build/macosx/Juce.xcodeproj/project.pbxproj index c3c6f510c0..4432e18a88 100644 --- a/build/macosx/Juce.xcodeproj/project.pbxproj +++ b/build/macosx/Juce.xcodeproj/project.pbxproj @@ -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 = ""; }; 8473E6521125974600D74E02 /* juce_Range.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = juce_Range.h; sourceTree = ""; }; + 84751E591132EE9E00640F9A /* juce_MouseInputSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = juce_MouseInputSource.cpp; sourceTree = ""; }; + 84751E5A1132EE9E00640F9A /* juce_MouseInputSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = juce_MouseInputSource.h; sourceTree = ""; }; 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 = ""; }; 84816E5310809D07008FEC33 /* juce_iphone_MessageManager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = juce_iphone_MessageManager.mm; sourceTree = ""; }; @@ -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; }; diff --git a/build/win32/vc8/JUCE.vcproj b/build/win32/vc8/JUCE.vcproj index dca56883e8..81e77f96a1 100644 --- a/build/win32/vc8/JUCE.vcproj +++ b/build/win32/vc8/JUCE.vcproj @@ -1931,6 +1931,14 @@ RelativePath="..\..\..\src\gui\components\mouse\juce_MouseHoverDetector.h" > + + + + diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index 190308fb54..cf59a0ffaf 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -3677,7 +3677,7 @@ DynamicObject* var::getObject() const return type == objectType ? value.objectValue : 0; } -bool var::operator== (const var& other) const throw() +bool var::equals (const var& other) const throw() { switch (type) { @@ -3694,10 +3694,10 @@ bool var::operator== (const var& other) const throw() return false; } -bool var::operator!= (const var& other) const throw() -{ - return ! operator== (other); -} +bool operator== (const var& v1, const var& v2) throw() { return v1.equals (v2); } +bool operator!= (const var& v1, const var& v2) throw() { return ! v1.equals (v2); } +bool operator== (const var& v1, const String& v2) throw() { return v1.toString() == v2; } +bool operator!= (const var& v1, const String& v2) throw() { return v1.toString() != v2; } void var::writeToStream (OutputStream& output) const { @@ -5608,23 +5608,23 @@ int OutputStream::writeFromInputStream (InputStream& source, int numBytesToWrite return numWritten; } -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; @@ -10839,52 +10839,52 @@ String& String::operator= (const String& other) throw() return *this; } -bool JUCE_PUBLIC_FUNCTION operator== (const String& string1, const String& string2) throw() +bool operator== (const String& string1, const String& string2) throw() { return string1.compare (string2) == 0; } -bool JUCE_PUBLIC_FUNCTION operator== (const String& string1, const char* string2) throw() +bool operator== (const String& string1, const char* string2) throw() { return string1.compare (string2) == 0; } -bool JUCE_PUBLIC_FUNCTION operator== (const String& string1, const juce_wchar* string2) throw() +bool operator== (const String& string1, const juce_wchar* string2) throw() { return string1.compare (string2) == 0; } -bool JUCE_PUBLIC_FUNCTION operator!= (const String& string1, const String& string2) throw() +bool operator!= (const String& string1, const String& string2) throw() { return string1.compare (string2) != 0; } -bool JUCE_PUBLIC_FUNCTION operator!= (const String& string1, const char* string2) throw() +bool operator!= (const String& string1, const char* string2) throw() { return string1.compare (string2) != 0; } -bool JUCE_PUBLIC_FUNCTION operator!= (const String& string1, const juce_wchar* string2) throw() +bool operator!= (const String& string1, const juce_wchar* string2) throw() { return string1.compare (string2) != 0; } -bool JUCE_PUBLIC_FUNCTION operator> (const String& string1, const String& string2) throw() +bool operator> (const String& string1, const String& string2) throw() { return string1.compare (string2) > 0; } -bool JUCE_PUBLIC_FUNCTION operator< (const String& string1, const String& string2) throw() +bool operator< (const String& string1, const String& string2) throw() { return string1.compare (string2) < 0; } -bool JUCE_PUBLIC_FUNCTION operator>= (const String& string1, const String& string2) throw() +bool operator>= (const String& string1, const String& string2) throw() { return string1.compare (string2) >= 0; } -bool JUCE_PUBLIC_FUNCTION operator<= (const String& string1, const String& string2) throw() +bool operator<= (const String& string1, const String& string2) throw() { return string1.compare (string2) <= 0; } @@ -10995,114 +10995,114 @@ void String::append (const tchar* const other, const int howMany) } } -const String JUCE_PUBLIC_FUNCTION operator+ (const char* const string1, const String& string2) +const String operator+ (const char* const string1, const String& string2) { String s (string1); return s += string2; } -const String JUCE_PUBLIC_FUNCTION operator+ (const juce_wchar* const string1, const String& string2) +const String operator+ (const juce_wchar* const string1, const String& string2) { String s (string1); return s += string2; } -const String JUCE_PUBLIC_FUNCTION operator+ (const char string1, const String& string2) +const String operator+ (const char string1, const String& string2) { return String::charToString (string1) + string2; } -const String JUCE_PUBLIC_FUNCTION operator+ (const juce_wchar string1, const String& string2) +const String operator+ (const juce_wchar string1, const String& string2) { return String::charToString (string1) + string2; } -const String JUCE_PUBLIC_FUNCTION operator+ (String string1, const String& string2) +const String operator+ (String string1, const String& string2) { return string1 += string2; } -const String JUCE_PUBLIC_FUNCTION operator+ (String string1, const char* const string2) +const String operator+ (String string1, const char* const string2) { return string1 += string2; } -const String JUCE_PUBLIC_FUNCTION operator+ (String string1, const juce_wchar* const string2) +const String operator+ (String string1, const juce_wchar* const string2) { return string1 += string2; } -const String JUCE_PUBLIC_FUNCTION operator+ (String string1, const char string2) +const String operator+ (String string1, const char string2) { return string1 += string2; } -const String JUCE_PUBLIC_FUNCTION operator+ (String string1, const juce_wchar string2) +const String operator+ (String string1, const juce_wchar string2) { return string1 += string2; } -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const char characterToAppend) +String& operator<< (String& string1, const char characterToAppend) { return string1 += characterToAppend; } -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const juce_wchar characterToAppend) +String& operator<< (String& string1, const juce_wchar characterToAppend) { return string1 += characterToAppend; } -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const char* const string2) +String& operator<< (String& string1, const char* const string2) { return string1 += string2; } -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const juce_wchar* const string2) +String& operator<< (String& string1, const juce_wchar* const string2) { return string1 += string2; } -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const String& string2) +String& operator<< (String& string1, const String& string2) { return string1 += string2; } -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const short number) +String& operator<< (String& string1, const short number) { return string1 += (int) number; } -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const int number) +String& operator<< (String& string1, const int number) { return string1 += number; } -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const unsigned int number) +String& operator<< (String& string1, const unsigned int number) { return string1 += number; } -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const long number) +String& operator<< (String& string1, const long number) { return string1 += (int) number; } -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const unsigned long number) +String& operator<< (String& string1, const unsigned long number) { return string1 += (unsigned int) number; } -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const float number) +String& operator<< (String& string1, const float number) { return string1 += String (number); } -String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const double number) +String& operator<< (String& string1, const double number) { return string1 += String (number); } -OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const String& text) +OutputStream& operator<< (OutputStream& stream, const String& text) { // (This avoids using toUTF8() to prevent the memory bloat that it would leave behind // if lots of large, persistent strings were to be written to streams). @@ -12471,6 +12471,11 @@ const char* String::toCString() const } } +#ifdef _MSC_VER + #pragma warning (disable: 4514 4996) + #pragma warning (push) +#endif + int String::getNumBytesAsCString() const throw() { return (int) wcstombs (0, text->text, 0); @@ -12486,6 +12491,10 @@ int String::copyToCString (char* destBuffer, const int maxBufferSizeBytes) const return numBytes; } +#ifdef _MSC_VER + #pragma warning (pop) +#endif + void String::copyToUnicode (juce_wchar* const destBuffer, const int maxCharsToCopy) const throw() { const int len = jmin (maxCharsToCopy, length()); @@ -32033,7 +32042,7 @@ public: { FSRef fn; - if (FSPathMakeRef ((UInt8*) (const char*) filename, &fn, 0) == noErr) + if (FSPathMakeRef ((UInt8*) filename.toUTF8(), &fn, 0) == noErr) { resFileId = FSOpenResFile (&fn, fsRdPerm); @@ -39505,7 +39514,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 (x, y), true); } } @@ -40624,7 +40633,7 @@ void Component::removeMouseListener (MouseListener* const listenerToRemove) thro } } -void Component::internalMouseEnter (int x, int y, int64 time) +void Component::internalMouseEnter (MouseInputSource& source, const Point& relativePos, const Time& time) { if (isCurrentlyBlockedByAnotherModalComponent()) { @@ -40654,13 +40663,9 @@ void Component::internalMouseEnter (int x, int y, int64 time) if (flags.repaintOnMouseActivityFlag) repaint(); - const MouseEvent me (Point (x, y), - ModifierKeys::getCurrentModifiers(), - this, - Time (time), - Point (x, y), - Time (time), - 0, false); + const MouseEvent me (source, relativePos, source.getCurrentModifiers(), + this, time, relativePos, + time, 0, false); mouseEnter (me); @@ -40716,13 +40721,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& 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; @@ -40739,13 +40744,9 @@ void Component::internalMouseExit (int x, int y, int64 time) if (flags.repaintOnMouseActivityFlag) repaint(); - const MouseEvent me (Point (x, y), - ModifierKeys::getCurrentModifiers(), - this, - Time (time), - Point (x, y), - Time (time), - 0, false); + const MouseEvent me (source, relativePos, source.getCurrentModifiers(), + this, time, relativePos, + time, 0, false); mouseExit (me); if (deletionChecker.hasBeenDeleted()) @@ -40800,23 +40801,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 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 @@ -40826,30 +40837,25 @@ 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& relativePos, const Time& time) { Desktop& desktop = Desktop::getInstance(); - desktop.registerMouseDown (relativePositionToGlobal (Point (x, y)), time, this); - const ComponentDeletionWatcher deletionChecker (this); if (isCurrentlyBlockedByAnotherModalComponent()) @@ -40864,14 +40870,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 (x, y), - ModifierKeys::getCurrentModifiers(), - this, - Time (time), - Point (x, y), - desktop.getLastMouseDownTime(), - desktop.getNumberOfMultipleClicks(), - false); + const MouseEvent me (source, relativePos, source.getCurrentModifiers(), + this, time, relativePos, time, + source.getNumberOfMultipleClicks(), false); desktop.resetTimer(); @@ -40917,14 +40918,9 @@ void Component::internalMouseDown (const int x, const int y, const int64 time) if (flags.repaintOnMouseActivityFlag) repaint(); - const MouseEvent me (Point (x, y), - ModifierKeys::getCurrentModifiers(), - this, - desktop.getLastMouseDownTime(), - Point (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()) @@ -40976,37 +40972,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& 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 (x, y))); const ComponentDeletionWatcher deletionChecker (this); if (flags.repaintOnMouseActivityFlag) repaint(); - const Point mouseDownPos (globalPositionToRelative (Desktop::getLastMouseDownPosition())); - const Time lastMouseDownTime (desktop.getLastMouseDownTime()); - - const MouseEvent me (Point (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); @@ -41114,33 +41098,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& 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 (x, y))); + flags.mouseOverFlag = reallyContains (relativePos.getX(), relativePos.getY(), false); const ComponentDeletionWatcher deletionChecker (this); - const Point mouseDownPos (globalPositionToRelative (Desktop::getLastMouseDownPosition())); - const Time lastMouseDownTime (desktop.getLastMouseDownTime()); - - const MouseEvent me (Point (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); @@ -41195,8 +41168,8 @@ void Component::internalMouseDrag (int x, int y, const int64 time) { if (isUnboundedMouseModeOn) { - Rectangle screenArea (getParentMonitorArea().expanded (-2, -2)); - Point mousePos (Desktop::getMousePosition()); + const Rectangle screenArea (getParentMonitorArea().expanded (-2, -2)); + Point mousePos (source.getScreenPosition()); if (! screenArea.contains (mousePos)) { @@ -41228,7 +41201,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& relativePos, const Time& time) { const ComponentDeletionWatcher deletionChecker (this); @@ -41236,13 +41209,9 @@ void Component::internalMouseMove (const int x, const int y, const int64 time) { Desktop& desktop = Desktop::getInstance(); - const MouseEvent me (Point (x, y), - ModifierKeys::getCurrentModifiers(), - this, - Time (time), - Point (x, y), - Time (time), - 0, false); + const MouseEvent me (source, relativePos, source.getCurrentModifiers(), + this, time, relativePos, + time, 0, false); if (isCurrentlyBlockedByAnotherModalComponent()) { @@ -41308,23 +41277,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& 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 Point mousePos (getMouseXYRelative()); + const float wheelIncrementX = amountX * (1.0f / 256.0f); + const float wheelIncrementY = amountY * (1.0f / 256.0f); - 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()) { @@ -41387,17 +41350,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() @@ -41925,10 +41883,12 @@ BEGIN_JUCE_NAMESPACE 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(); } @@ -42090,7 +42050,7 @@ void Desktop::componentBroughtToFront (Component* const c) throw() const Point Desktop::getLastMouseDownPosition() throw() { - return getInstance().mouseDowns[0].position; + return getInstance().getMainMouseSource().getLastMouseDownPosition(); } int Desktop::getMouseButtonClickCounter() throw() @@ -42103,59 +42063,6 @@ void Desktop::incrementMouseClickCounter() throw() ++mouseClickCounter; } -const Time Desktop::getLastMouseDownTime() const throw() -{ - return Time (mouseDowns[0].time); -} - -void Desktop::registerMouseDown (const Point& 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& 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() { jassert (listener != 0); @@ -42222,7 +42129,7 @@ void Desktop::sendMouseMove() const Point 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;) @@ -49634,35 +49541,32 @@ void Slider::restoreMouseIfHidden() : ((sliderBeingDragged == 1) ? getMinValue() : (double) currentValue.getValue()); + Point mousePos; + if (style == RotaryHorizontalDrag || style == RotaryVerticalDrag) { - Point mousePos (Desktop::getMousePosition()); - const Point lastMouseDown (Desktop::getLastMouseDownPosition()); + mousePos = Desktop::getLastMouseDownPosition(); if (style == RotaryHorizontalDrag) { const double posDiff = valueToProportionOfLength (pos) - valueToProportionOfLength (valueOnMouseDown); - mousePos = Point (roundToInt (pixelsForFullDragExtent * posDiff + lastMouseDown.getX()), - lastMouseDown.getY()); + mousePos += Point (roundToInt (pixelsForFullDragExtent * posDiff), 0); } else { const double posDiff = valueToProportionOfLength (valueOnMouseDown) - valueToProportionOfLength (pos); - mousePos = Point (lastMouseDown.getX(), - roundToInt (pixelsForFullDragExtent * posDiff + lastMouseDown.getY())); + mousePos += Point (0, roundToInt (pixelsForFullDragExtent * posDiff)); } - - Desktop::setMousePosition (mousePos); } else { const int pixelPos = (int) getLinearSliderPos (pos); - const Point pos (isHorizontal() ? pixelPos : (getWidth() / 2), - isVertical() ? pixelPos : (getHeight() / 2)); - - Desktop::setMousePosition (relativePositionToGlobal (pos)); + mousePos = relativePositionToGlobal (Point (isHorizontal() ? pixelPos : (getWidth() / 2), + isVertical() ? pixelPos : (getHeight() / 2))); } + + Desktop::setMousePosition (mousePos); } } @@ -52618,7 +52522,7 @@ void TextEditor::repaintText (const Range& range) if (range.getEnd() >= getTotalNumChars()) { - y2 = getHeight(); + y2 = textHolder->getHeight(); } else { @@ -55140,12 +55044,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())); } } @@ -55171,12 +55071,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())); } } @@ -60401,11 +60296,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() @@ -70410,7 +70305,8 @@ END_JUCE_NAMESPACE /*** Start of inlined file: juce_MouseEvent.cpp ***/ BEGIN_JUCE_NAMESPACE -MouseEvent::MouseEvent (const Point& position, +MouseEvent::MouseEvent (MouseInputSource& source_, + const Point& position, const ModifierKeys& mods_, Component* const originator, const Time& eventTime_, @@ -70424,6 +70320,7 @@ MouseEvent::MouseEvent (const Point& position, eventComponent (originator), originalComponent (originator), eventTime (eventTime_), + source (source_), mouseDownPos (mouseDownPos_), mouseDownTime (mouseDownTime_), numberOfClicks (numberOfClicks_), @@ -70435,6 +70332,27 @@ 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& newPosition) const throw() +{ + return MouseEvent (source, newPosition, mods, originalComponent, + eventTime, mouseDownPos, mouseDownTime, + numberOfClicks, wasMovedSinceMouseDown); +} + bool MouseEvent::mouseWasClicked() const throw() { return ! wasMovedSinceMouseDown; @@ -70467,8 +70385,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() @@ -70514,24 +70431,6 @@ const Point 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 (x, y)), - mods, - originalComponent, - eventTime, - eventComponent->relativePositionToOtherComponent (otherComponent, mouseDownPos), - mouseDownTime, - numberOfClicks, - wasMovedSinceMouseDown); -} - static int doubleClickTimeOutMs = 400; void MouseEvent::setDoubleClickTimeout (const int newTime) throw() @@ -70548,6 +70447,343 @@ END_JUCE_NAMESPACE /*** End of inlined file: juce_MouseEvent.cpp ***/ +/*** Start of inlined file: juce_MouseInputSource.cpp ***/ +BEGIN_JUCE_NAMESPACE + +class MouseInputSourceInternal : public AsyncUpdater +{ +public: + MouseInputSourceInternal (MouseInputSource& source_, const int index_, const bool isMouseDevice_) + : index (index_), isMouseDevice (isMouseDevice_), source (source_), lastPeer (0), lastTime (0) + { + zerostruct (mouseDowns); + } + + ~MouseInputSourceInternal() + { + } + + bool isDragging() const throw() + { + return buttonState.isAnyMouseButtonDown(); + } + + Component* getComponentUnderMouse() const + { + return componentUnderMouse != 0 ? const_cast (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& screenPos) + { + ComponentPeer* const peer = getPeer(); + + if (peer != 0) + { + Component* const comp = peer->getComponent(); + const Point 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& 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& screenPos, const int64 time) + { + Component* current = getComponentUnderMouse(); + + if (newComponent != current) + { + ScopedPointer 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& screenPos, const int64 time) + { + ModifierKeys::updateCurrentModifiers(); + + if (newPeer != lastPeer) + { + setComponentUnderMouse (0, screenPos, time); + lastPeer = newPeer; + setComponentUnderMouse (findComponentAt (screenPos), screenPos, time); + } + } + + void setScreenPos (const Point& 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 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& positionWithinPeer, const int64 time, const ModifierKeys& newMods) + { + jassert (newPeer != 0); + lastTime = time; + const Point 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& positionWithinPeer, int64 time, float x, float y) + { + jassert (peer != 0); + lastTime = time; + const Point 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 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 lastScreenPos; + ModifierKeys buttonState; + +private: + MouseInputSource& source; + ScopedPointer componentUnderMouse; + ComponentPeer* lastPeer; + + struct RecentMouseDown + { + Point position; + int64 time; + Component* component; + }; + + RecentMouseDown mouseDowns[4]; + bool mouseMovedSignificantlySincePressed; + int64 lastTime; + + void registerMouseDown (const Point& 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& 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 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 MouseInputSource::getLastMouseDownPosition() const throw() { return pimpl->getLastMouseDownPosition(); } +bool MouseInputSource::hasMouseMovedSignificantlySincePressed() const throw() { return pimpl->hasMouseMovedSignificantlySincePressed(); } + +void MouseInputSource::handleEvent (ComponentPeer* peer, const Point& positionWithinPeer, const int64 time, const ModifierKeys& mods) +{ + pimpl->handleEvent (peer, positionWithinPeer, time, mods.withOnlyMouseButtons()); +} + +void MouseInputSource::handleWheel (ComponentPeer* const peer, const Point& positionWithinPeer, const int64 time, const float x, const float y) +{ + pimpl->handleWheel (peer, positionWithinPeer, time, x, y); +} + +END_JUCE_NAMESPACE +/*** End of inlined file: juce_MouseInputSource.cpp ***/ + + /*** Start of inlined file: juce_MouseHoverDetector.cpp ***/ BEGIN_JUCE_NAMESPACE @@ -73924,10 +74160,10 @@ public: roundToInt (p.getY() / zoom)); } - bool contains (int x, int y, bool) const + bool contains (const Point& 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) @@ -74002,7 +74238,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); @@ -74094,48 +74331,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 (scaleInt (e.x), scaleInt (e.y)), e.eventTime.toMilliseconds()); + mouseSource.handleEvent (peer, Point (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 (scaleInt (e.x), scaleInt (e.y)), e.eventTime.toMilliseconds()); + passOnMouseEventToPeer (e); } void MagnifierComponent::mouseDrag (const MouseEvent& e) { - if (peer != 0) - peer->handleMouseDrag (Point (scaleInt (e.x), scaleInt (e.y)), e.eventTime.toMilliseconds()); + passOnMouseEventToPeer (e); } void MagnifierComponent::mouseMove (const MouseEvent& e) { - if (peer != 0) - peer->handleMouseMove (Point (scaleInt (e.x), scaleInt (e.y)), e.eventTime.toMilliseconds()); + passOnMouseEventToPeer (e); } void MagnifierComponent::mouseEnter (const MouseEvent& e) { - if (peer != 0) - peer->handleMouseEnter (Point (scaleInt (e.x), scaleInt (e.y)), e.eventTime.toMilliseconds()); + passOnMouseEventToPeer (e); } void MagnifierComponent::mouseExit (const MouseEvent& e) { - if (peer != 0) - peer->handleMouseExit (Point (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 (scaleInt (e.x), scaleInt (e.y)), e.eventTime.toMilliseconds(), + ix * 256.0f, iy * 256.0f); else Component::mouseWheelMove (e, ix, iy); } @@ -76096,7 +76333,6 @@ BEGIN_JUCE_NAMESPACE //#define JUCE_ENABLE_REPAINT_DEBUGGING 1 -static const int fakeMouseMoveMessage = 0x7fff00ff; static VoidArray heavyweightPeers; ComponentPeer::ComponentPeer (Component* const component_, @@ -76153,203 +76389,14 @@ void ComponentPeer::updateCurrentModifiers() throw() ModifierKeys::updateCurrentModifiers(); } -void ComponentPeer::handleMouseEnter (const Point& position, const int64 time) +void ComponentPeer::handleMouseEvent (const Point& 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 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 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& position, const int64 time) +void ComponentPeer::handleMouseWheel (const Point& 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 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 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 relPos (component->relativePositionToOtherComponent (Component::componentUnderMouse, position)); - Component::componentUnderMouse->internalMouseMove (relPos.getX(), relPos.getY(), time); - } -} - -void ComponentPeer::handleMouseDown (const Point& position, const int64 time) -{ - Desktop::getInstance().incrementMouseClickCounter(); - updateCurrentModifiers(); - - if (ModifierKeys::getCurrentModifiers().getNumMouseButtonsDown() == 1) - { - Component::componentUnderMouse = component->getComponentAt (position); - - if (Component::componentUnderMouse != 0) - { - const Point relPos (component->relativePositionToOtherComponent (Component::componentUnderMouse, position)); - Component::componentUnderMouse->internalMouseDown (relPos.getX(), relPos.getY(), time); - } - } -} - -void ComponentPeer::handleMouseDrag (const Point& position, const int64 time) -{ - updateCurrentModifiers(); - - if (Component::componentUnderMouse != 0) - { - const Point relPos (component->relativePositionToOtherComponent (Component::componentUnderMouse, position)); - Component::componentUnderMouse->internalMouseDrag (relPos.getX(), relPos.getY(), time); - } -} - -void ComponentPeer::handleMouseUp (const int oldModifiers, const Point& 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 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 relPos (component->relativePositionToOtherComponent (Component::componentUnderMouse, position)); - Component::componentUnderMouse->internalMouseEnter (relPos.getX(), relPos.getY(), time); - } - } - else - { - if (Component::componentUnderMouse != 0) - { - const Point relPos (component->relativePositionToOtherComponent (Component::componentUnderMouse, position)); - Component::componentUnderMouse->internalMouseUp (oldModifiers, relPos.getX(), relPos.getY(), time); - } - } - } -} - -void ComponentPeer::handleMouseExit (const Point& position, const int64 time) -{ - jassert (component->isValidComponent()); - updateCurrentModifiers(); - - if (Component::componentUnderMouse != 0) - { - const Point 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 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 (message.intParameter2, message.intParameter3), - Time::currentTimeMillis()); - } + Desktop::getInstance().getMainMouseSource().handleWheel (this, positionWithinPeer, time, x, y); } void ComponentPeer::handlePaint (LowLevelGraphicsContext& contextToPaintTo) @@ -81647,7 +81694,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)]; @@ -81690,7 +81737,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; @@ -81727,7 +81774,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; @@ -214536,33 +214583,6 @@ private: 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; @@ -214589,39 +214609,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()) @@ -214864,17 +214851,20 @@ public: return wp.showCmd == SW_SHOWMAXIMIZED; } - bool contains (int x, int y, bool trueIfInAChildWindow) const + bool contains (const Point& 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)); } @@ -215045,10 +215035,50 @@ 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; @@ -215444,19 +215474,17 @@ private: #endif } - void doMouseMove (const int x, const int y) + void doMouseEvent (const Point& 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& position) + { if (! isMouseOver) { isMouseOver = true; + updateKeyModifiers(); TRACKMOUSEEVENT tme; tme.cbSize = sizeof (tme); @@ -215465,151 +215493,63 @@ private: tme.dwHoverTime = 0; if (! TrackMouseEvent (&tme)) - { jassertfalse; - } - - updateKeyModifiers(); - handleMouseEnter (Point (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 (x, y), mouseEventTime); - } - } - } + if (! contains (position, false)) + return; } - else - { - const uint32 now = Time::getMillisecondCounter(); - if (now > lastMouseTime + 1000 / maxMouseMovesPerSecond) - { - lastMouseTime = now; - handleMouseDrag (Point (x, y), mouseEventTime); - } - } + doMouseEvent (position); } - void doMouseDown (const int x, const int y, const WPARAM wParam) + void doMouseDown (const Point& position, const WPARAM wParam) { if (GetCapture() != hwnd) SetCapture (hwnd); - doMouseMove (x, y); - - currentModifiers &= ~ModifierKeys::allMouseButtonModifiers; + doMouseMove (position); - 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 = true; - handleMouseDown (Point (x, y), getMouseEventTime()); + doMouseEvent (position); } - void doMouseUp (const int x, const int y, const WPARAM wParam) + void doMouseUp (const Point& 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 (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 (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& 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); } void sendModifierKeyChangeIfNeeded() @@ -215778,7 +215718,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; } @@ -215968,6 +215908,21 @@ public: } private: + static const Point getPointFromLParam (LPARAM lParam) throw() + { + return Point (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam)); + } + + const Point getCurrentMousePos() throw() + { + RECT wr; + GetWindowRect (hwnd, &wr); + const DWORD mp = GetMessagePos(); + + return Point (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)) @@ -216005,7 +215960,7 @@ private: return 1; case WM_MOUSEMOVE: - doMouseMove (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam)); + doMouseMove (getPointFromLParam (lParam)); return 0; case WM_MOUSELEAVE: @@ -216015,13 +215970,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: @@ -216035,11 +215990,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; case WM_WINDOWPOSCHANGING: @@ -216146,7 +216101,7 @@ private: component->repaint(); handleMovedOrResized(); - if (! isValidMessageListener()) + if (! ComponentPeer::isValidPeer (this)) return 0; } @@ -216220,31 +216175,31 @@ private: } else { - const int oldModifiers = currentModifiers; - - MouseEvent e (Point(), ModifierKeys::getCurrentModifiersRealtime(), component, - getMouseEventTime(), Point(), 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(), eventMods, component, getMouseEventTime(), + Point(), 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) @@ -216393,6 +216348,9 @@ private: Win32ComponentPeer& operator= (const Win32ComponentPeer&); }; +ModifierKeys Win32ComponentPeer::currentModifiers; +ModifierKeys Win32ComponentPeer::modifiersAtLastCallback; + ComponentPeer* Component::createNewPeer (int styleFlags, void* /*nativeWindowToAttachTo*/) { return new Win32ComponentPeer (this, styleFlags); @@ -216400,6 +216358,26 @@ 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) { Win32ComponentPeer* const wp = dynamic_cast (getPeer()); @@ -217967,217 +217945,267 @@ const String SystemClipboard::getTextFromClipboard() throw() // compiled on its own). #if JUCE_INCLUDED_FILE -class JuceIStorage : public IStorage +namespace ActiveXHelpers { - int refCount; - -public: - JuceIStorage() : refCount (1) {} - - virtual ~JuceIStorage() + class JuceIStorage : public IStorage { - jassert (refCount == 0); - } + int refCount; - HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result) - { - if (id == IID_IUnknown || id == IID_IStorage) + public: + JuceIStorage() : refCount (1) {} + + virtual ~JuceIStorage() { - AddRef(); - *result = this; - return S_OK; + jassert (refCount == 0); } - *result = 0; - return E_NOINTERFACE; - } + HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result) + { + if (id == IID_IUnknown || id == IID_IStorage) + { + AddRef(); + *result = this; + return S_OK; + } - 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; } + *result = 0; + return E_NOINTERFACE; + } - juce_UseDebuggingNewOperator -}; + ULONG __stdcall AddRef() { return ++refCount; } + ULONG __stdcall Release() { const int r = --refCount; if (r == 0) delete this; return r; } -class JuceOleInPlaceFrame : public IOleInPlaceFrame -{ - int refCount; - HWND window; + 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; } -public: - JuceOleInPlaceFrame (HWND window_) - : refCount (1), - window (window_) - { - } + juce_UseDebuggingNewOperator + }; - virtual ~JuceOleInPlaceFrame() + class JuceOleInPlaceFrame : public IOleInPlaceFrame { - jassert (refCount == 0); - } + int refCount; + HWND window; - HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result) - { - if (id == IID_IUnknown || id == IID_IOleInPlaceFrame) + 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 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; } + HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result) + { + if (id == IID_IUnknown || id == IID_IOleInPlaceFrame) + { + AddRef(); + *result = this; + return S_OK; + } - juce_UseDebuggingNewOperator -}; + *result = 0; + return E_NOINTERFACE; + } -class JuceIOleInPlaceSite : public IOleInPlaceSite -{ - int refCount; - HWND window; - JuceOleInPlaceFrame* frame; + ULONG __stdcall AddRef() { return ++refCount; } + ULONG __stdcall Release() { const int r = --refCount; if (r == 0) delete this; return r; } -public: - JuceIOleInPlaceSite (HWND window_) - : refCount (1), - window (window_) - { - frame = new JuceOleInPlaceFrame (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; } - virtual ~JuceIOleInPlaceSite() - { - jassert (refCount == 0); - frame->Release(); - } + juce_UseDebuggingNewOperator + }; - HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result) + class JuceIOleInPlaceSite : public IOleInPlaceSite { - if (id == IID_IUnknown || id == IID_IOleInPlaceSite) + 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; - } + virtual ~JuceIOleInPlaceSite() + { + jassert (refCount == 0); + frame->Release(); + } - 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 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) - { - // 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; - } + HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result) + { + if (id == IID_IUnknown || id == IID_IOleInPlaceSite) + { + AddRef(); + *result = this; + return S_OK; + } - 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; } + *result = 0; + return E_NOINTERFACE; + } - juce_UseDebuggingNewOperator -}; + ULONG __stdcall AddRef() { return ++refCount; } + ULONG __stdcall Release() { const int r = --refCount; if (r == 0) delete this; return r; } -class JuceIOleClientSite : public IOleClientSite -{ - int refCount; - JuceIOleInPlaceSite* inplaceSite; + 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) + { + // 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; + } -public: - JuceIOleClientSite (HWND window) - : refCount (1) - { - inplaceSite = new JuceIOleInPlaceSite (window); - } + 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; } - virtual ~JuceIOleClientSite() - { - jassert (refCount == 0); - inplaceSite->Release(); - } + juce_UseDebuggingNewOperator + }; - HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result) + class JuceIOleClientSite : public IOleClientSite { - if (id == IID_IUnknown || id == IID_IOleClientSite) + int refCount; + JuceIOleInPlaceSite* inplaceSite; + + public: + JuceIOleClientSite (HWND window) + : refCount (1) { - AddRef(); - *result = this; - return S_OK; + inplaceSite = new JuceIOleInPlaceSite (window); } - else if (id == IID_IOleInPlaceSite) + + virtual ~JuceIOleClientSite() { - inplaceSite->AddRef(); - *result = inplaceSite; - return S_OK; + jassert (refCount == 0); + inplaceSite->Release(); } - *result = 0; - return E_NOINTERFACE; + 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; + } + + *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 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 + }; + + 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; } - 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 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; @@ -218194,8 +218222,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) { } @@ -218247,123 +218275,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 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) + // 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) { - 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;) - { - 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()) - { - ComponentPeer* const peer = ax->getPeer(); - - if (peer != 0) + switch (message) + { + 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) @@ -218407,12 +218378,12 @@ bool ActiveXControlComponent::createControl (const void* controlIID) control = info.release(); setControlBounds (Rectangle (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; @@ -221934,6 +221905,9 @@ public: private: Pimpl& pimpl; + + ScopedDiscOpener (const ScopedDiscOpener&); + ScopedDiscOpener& operator= (const ScopedDiscOpener&); }; DiskState getDiskState() @@ -222109,6 +222083,8 @@ int AudioCDBurner::getNumAvailableAudioBlocks() const const String AudioCDBurner::burn (AudioCDBurner::BurnProgressListener* listener, bool ejectDiscAfterwards, bool performFakeBurnForTesting, int writeSpeed) { + pimpl->setIntProperty (L"WriteSpeed", writeSpeed > 0 ? writeSpeed : -1); + pimpl->listener = listener; pimpl->progress = 0; pimpl->shouldCancel = false; @@ -231609,33 +231585,6 @@ enum MouseButtons WheelDown = 5 }; -static const Point 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 (x, y); -} - static int AltMask = 0; static int NumLockMask = 0; static bool numLock = 0; @@ -231688,123 +231637,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() { @@ -232088,7 +231920,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.. @@ -232126,7 +231957,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; } @@ -232336,9 +232167,10 @@ public: return result; } - bool contains (int x, int y, bool trueIfInAChildWindow) const + bool contains (const Point& 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) @@ -232647,10 +232479,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); @@ -232748,7 +232579,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) @@ -232763,48 +232594,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 (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 (buttonPressEvent->x, buttonPressEvent->y), - getEventTime (buttonPressEvent->time)); - } - else if (wheelUpMsg || wheelDownMsg) - { - handleMouseWheel (0, wheelDownMsg ? -84 : 84, + + handleMouseEvent (Point (buttonPressEvent->x, buttonPressEvent->y), currentModifiers, getEventTime (buttonPressEvent->time)); } @@ -232815,22 +232635,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 (buttonRelEvent->x, buttonRelEvent->y), - getEventTime (buttonRelEvent->time)); + handleMouseEvent (Point (buttonRelEvent->x, buttonRelEvent->y), currentModifiers, + getEventTime (buttonRelEvent->time)); clearLastMousePos(); break; @@ -232839,10 +232656,9 @@ public: case MotionNotify: { const XPointerMovedEvent* const movedEvent = (const XPointerMovedEvent*) &event->xmotion; - updateKeyModifiers (movedEvent->state); - Point mousePos (Desktop::getMousePosition()); + const Point mousePos (Desktop::getMousePosition()); if (lastMousePos != mousePos) { @@ -232851,37 +232667,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; @@ -232892,14 +232699,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 (enterEvent->x, enterEvent->y), getEventTime (enterEvent->time)); - - entered = true; + handleMouseEvent (Point (enterEvent->x, enterEvent->y), currentModifiers, getEventTime (enterEvent->time)); } break; @@ -232912,15 +232715,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 (leaveEvent->x, leaveEvent->y), getEventTime (leaveEvent->time)); - - entered = false; + handleMouseEvent (Point (leaveEvent->x, leaveEvent->y), currentModifiers, getEventTime (leaveEvent->time)); } break; @@ -233051,7 +232850,7 @@ public: // Deal with modifier/keyboard mapping ScopedXLock xlock; XRefreshKeyboardMapping (mappingEvent); - getModifierMapping(); + updateModifierMappings(); } break; @@ -233205,6 +233004,8 @@ public: bool dontRepaint; + static ModifierKeys currentModifiers; + private: class LinuxRepaintManager : public Timer @@ -233349,7 +233150,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 @@ -233361,6 +233162,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) { Atom hints = XInternAtom (display, "_MOTIF_WM_HINTS", True); @@ -233673,7 +233568,7 @@ private: } } - getModifierMapping(); + updateModifierMappings(); } windowH = wndH; @@ -233698,7 +233593,7 @@ private: {} } - static int64 getEventTime (::Time t) throw() + static int64 getEventTime (::Time t) { static int64 eventTimeOffset = 0x12345678; const int64 thisMessageTime = t; @@ -234043,9 +233938,36 @@ private: } }; +ModifierKeys LinuxComponentPeer::currentModifiers; int LinuxComponentPeer::pointerMap[5]; Point 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) { if (enableOrDisable) @@ -234191,8 +234113,22 @@ bool Desktop::canUseSemiTransparentWindows() throw() const Point 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 (x, y); } void Desktop::setMousePosition (const Point& newPosition) @@ -240800,7 +240736,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& position, bool trueIfInAChildWindow) const; const BorderSize getFrameSize() const; bool setAlwaysOnTop (bool alwaysOnTop); void toFront (bool makeActiveWindow); @@ -240829,6 +240765,7 @@ public: UIWindow* window; JuceUIView* view; bool isSharedWindow, fullScreen, insideDrawRect; + static ModifierKeys currentModifiers; }; END_JUCE_NAMESPACE @@ -240860,23 +240797,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) @@ -240900,13 +240830,15 @@ JUCE_NAMESPACE::Point juce_lastMousePos; { CGPoint p = [[t objectAtIndex: 0] locationInView: self]; const JUCE_NAMESPACE::Point 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: @@ -240930,7 +240862,7 @@ JUCE_NAMESPACE::Point juce_lastMousePos; const JUCE_NAMESPACE::Point 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: @@ -240954,9 +240886,10 @@ JUCE_NAMESPACE::Point juce_lastMousePos; const JUCE_NAMESPACE::Point 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: @@ -241245,15 +241178,15 @@ bool UIViewComponentPeer::isFullScreen() const return fullScreen; } -bool UIViewComponentPeer::contains (int x, int y, bool trueIfInAChildWindow) const +bool UIViewComponentPeer::contains (const Point& 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]; @@ -245263,7 +245196,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& position, bool trueIfInAChildWindow) const; const BorderSize getFrameSize() const; bool setAlwaysOnTop (bool alwaysOnTop); void toFront (bool makeActiveWindow); @@ -245280,6 +245213,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); @@ -245352,6 +245286,10 @@ public: NSWindow* window; JuceNSView* view; bool isSharedWindow, fullScreen, insideDrawRect, usingCoreGraphics, recursiveToFrontCall; + + static ModifierKeys currentModifiers; + static ComponentPeer* currentlyFocusedPeer; + static VoidArray keysCurrentlyDown; }; END_JUCE_NAMESPACE @@ -245828,45 +245766,36 @@ 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) @@ -245885,12 +245814,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; } NSViewComponentPeer::NSViewComponentPeer (Component* const component_, @@ -246184,15 +246113,15 @@ bool NSViewComponentPeer::isFullScreen() const return fullScreen; } -bool NSViewComponentPeer::contains (int x, int y, bool trueIfInAChildWindow) const +bool NSViewComponentPeer::contains (const Point& 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]; @@ -246303,19 +246232,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); @@ -246431,55 +246360,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() diff --git a/juce_amalgamated.h b/juce_amalgamated.h index bde8e39329..de9ad27aef 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -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 std::basic_ostream & operator<< (std::basic_ostream & stream, const String& stringToWrite) @@ -1427,7 +1427,7 @@ std::basic_ostream & operator<< (std::basic_ostream & position, + MouseEvent (MouseInputSource& source, + const Point& 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& newPosition) const throw(); + static void setDoubleClickTimeout (const int timeOutMilliseconds) throw(); static int getDoubleClickTimeout() throw(); @@ -9227,42 +9278,17 @@ public: juce_UseDebuggingNewOperator private: - Point mouseDownPos; - Time mouseDownTime; - int numberOfClicks; - bool wasMovedSinceMouseDown; + const Point 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& position, bool trueIfInAChildWindow) const = 0; virtual const BorderSize getFrameSize() const = 0; @@ -12089,15 +12115,8 @@ public: virtual void performAnyPendingRepaintsNow() = 0; - void handleMouseEnter (const Point& position, const int64 time); - void handleMouseMove (const Point& position, const int64 time); - void handleMouseDown (const Point& position, const int64 time); - void handleMouseDrag (const Point& position, const int64 time); - void handleMouseUp (const int oldModifiers, const Point& position, const int64 time); - void handleMouseExit (const Point& position, const int64 time); - void handleMouseWheel (const int amountX, const int amountY, const int64 time); - - void sendFakeMouseMove() throw(); + void handleMouseEvent (const Point& positionWithinPeer, const ModifierKeys& newMods, const int64 time); + void handleMouseWheel (const Point& 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& relativePos, const Time& time); + void internalMouseExit (MouseInputSource& source, const Point& relativePos, const Time& time); + void internalMouseDown (MouseInputSource& source, const Point& relativePos, const Time& time); + void internalMouseUp (MouseInputSource& source, const Point& relativePos, const Time& time, const ModifierKeys& oldModifiers); + void internalMouseDrag (MouseInputSource& source, const Point& relativePos, const Time& time); + void internalMouseMove (MouseInputSource& source, const Point& relativePos, const Time& time); + void internalMouseWheel (MouseInputSource& source, const Point& 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 mouseListeners, focusListeners; Array desktopComponents; @@ -13073,24 +13104,12 @@ private: Array > monitorCoordsClipped, monitorCoordsUnclipped; + OwnedArray mouseSources; + Point lastFakeMouseMove; int mouseClickCounter; - bool mouseMovedSignificantlySincePressed; - - struct RecentMouseDown - { - Point position; - int64 time; - Component* component; - }; - - RecentMouseDown mouseDowns[4]; void incrementMouseClickCounter() throw(); - void registerMouseDown (const Point& position, int64 time, Component* component) throw(); - void registerMouseDrag (const Point& position) throw(); - const Time getLastMouseDownTime() const throw(); - int getNumberOfMultipleClicks() const throw(); Component* kioskModeComponent; Rectangle 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 getScreenPosition() const; + + const ModifierKeys getCurrentModifiers() const; + + Component* getComponentUnderMouse() const; + + void triggerFakeMove() const; + + int getNumberOfMultipleClicks() const throw(); + + const Time getLastMouseDownTime() const throw(); + + const Point getLastMouseDownPosition() const throw(); + + bool hasMouseMovedSignificantlySincePressed() const throw(); + + juce_UseDebuggingNewOperator + + void handleEvent (ComponentPeer* peer, const Point& positionWithinPeer, int64 time, const ModifierKeys& mods); + void handleWheel (ComponentPeer* peer, const Point& positionWithinPeer, int64 time, float x, float y); + +private: + friend class Desktop; + friend class ComponentPeer; + friend class MouseInputSourceInternal; + ScopedPointer 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&); diff --git a/src/containers/juce_Variant.h b/src/containers/juce_Variant.h index b9051eaebd..1d21041194 100644 --- a/src/containers/juce_Variant.h +++ b/src/containers/juce_Variant.h @@ -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 { diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h index b57a9a859a..179aeeb572 100644 --- a/src/core/juce_StandardHeader.h +++ b/src/core/juce_StandardHeader.h @@ -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. diff --git a/src/gui/components/controls/juce_Slider.cpp b/src/gui/components/controls/juce_Slider.cpp index 36ee4d5e6a..cbf2b15a0d 100644 --- a/src/gui/components/controls/juce_Slider.cpp +++ b/src/gui/components/controls/juce_Slider.cpp @@ -1148,35 +1148,32 @@ void Slider::restoreMouseIfHidden() : ((sliderBeingDragged == 1) ? getMinValue() : (double) currentValue.getValue()); + Point mousePos; + if (style == RotaryHorizontalDrag || style == RotaryVerticalDrag) { - Point mousePos (Desktop::getMousePosition()); - const Point lastMouseDown (Desktop::getLastMouseDownPosition()); + mousePos = Desktop::getLastMouseDownPosition(); if (style == RotaryHorizontalDrag) { const double posDiff = valueToProportionOfLength (pos) - valueToProportionOfLength (valueOnMouseDown); - mousePos = Point (roundToInt (pixelsForFullDragExtent * posDiff + lastMouseDown.getX()), - lastMouseDown.getY()); + mousePos += Point (roundToInt (pixelsForFullDragExtent * posDiff), 0); } else { const double posDiff = valueToProportionOfLength (valueOnMouseDown) - valueToProportionOfLength (pos); - mousePos = Point (lastMouseDown.getX(), - roundToInt (pixelsForFullDragExtent * posDiff + lastMouseDown.getY())); + mousePos += Point (0, roundToInt (pixelsForFullDragExtent * posDiff)); } - - Desktop::setMousePosition (mousePos); } else { const int pixelPos = (int) getLinearSliderPos (pos); - const Point pos (isHorizontal() ? pixelPos : (getWidth() / 2), - isVertical() ? pixelPos : (getHeight() / 2)); - - Desktop::setMousePosition (relativePositionToGlobal (pos)); + mousePos = relativePositionToGlobal (Point (isHorizontal() ? pixelPos : (getWidth() / 2), + isVertical() ? pixelPos : (getHeight() / 2))); } + + Desktop::setMousePosition (mousePos); } } diff --git a/src/gui/components/controls/juce_TreeView.cpp b/src/gui/components/controls/juce_TreeView.cpp index 0e3880e940..2d1bcf3b60 100644 --- a/src/gui/components/controls/juce_TreeView.cpp +++ b/src/gui/components/controls/juce_TreeView.cpp @@ -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())); } } diff --git a/src/gui/components/juce_Component.cpp b/src/gui/components/juce_Component.cpp index 851099ef6d..4bac896a0b 100644 --- a/src/gui/components/juce_Component.cpp +++ b/src/gui/components/juce_Component.cpp @@ -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 (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& 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 (x, y), - ModifierKeys::getCurrentModifiers(), - this, - Time (time), - Point (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& 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 (x, y), - ModifierKeys::getCurrentModifiers(), - this, - Time (time), - Point (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 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& relativePos, const Time& time) { Desktop& desktop = Desktop::getInstance(); - desktop.registerMouseDown (relativePositionToGlobal (Point (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 (x, y), - ModifierKeys::getCurrentModifiers(), - this, - Time (time), - Point (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 (x, y), - ModifierKeys::getCurrentModifiers(), - this, - desktop.getLastMouseDownTime(), - Point (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& 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 (x, y))); const ComponentDeletionWatcher deletionChecker (this); if (flags.repaintOnMouseActivityFlag) repaint(); - const Point mouseDownPos (globalPositionToRelative (Desktop::getLastMouseDownPosition())); - const Time lastMouseDownTime (desktop.getLastMouseDownTime()); - - const MouseEvent me (Point (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& 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 (x, y))); + flags.mouseOverFlag = reallyContains (relativePos.getX(), relativePos.getY(), false); const ComponentDeletionWatcher deletionChecker (this); - const Point mouseDownPos (globalPositionToRelative (Desktop::getLastMouseDownPosition())); - const Time lastMouseDownTime (desktop.getLastMouseDownTime()); - - const MouseEvent me (Point (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 screenArea (getParentMonitorArea().expanded (-2, -2)); - Point mousePos (Desktop::getMousePosition()); + const Rectangle screenArea (getParentMonitorArea().expanded (-2, -2)); + Point 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& 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 (x, y), - ModifierKeys::getCurrentModifiers(), - this, - Time (time), - Point (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& 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 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() diff --git a/src/gui/components/juce_Component.h b/src/gui/components/juce_Component.h index cbdef12ff1..c6cf29d27c 100644 --- a/src/gui/components/juce_Component.h +++ b/src/gui/components/juce_Component.h @@ -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& relativePos, const Time& time); + void internalMouseExit (MouseInputSource& source, const Point& relativePos, const Time& time); + void internalMouseDown (MouseInputSource& source, const Point& relativePos, const Time& time); + void internalMouseUp (MouseInputSource& source, const Point& relativePos, const Time& time, const ModifierKeys& oldModifiers); + void internalMouseDrag (MouseInputSource& source, const Point& relativePos, const Time& time); + void internalMouseMove (MouseInputSource& source, const Point& relativePos, const Time& time); + void internalMouseWheel (MouseInputSource& source, const Point& relativePos, const Time& time, const float amountX, const float amountY); void internalBroughtToFront(); void internalFocusGain (const FocusChangeType cause); void internalFocusLoss (const FocusChangeType cause); diff --git a/src/gui/components/juce_Desktop.cpp b/src/gui/components/juce_Desktop.cpp index 2d55551373..242ff4022b 100644 --- a/src/gui/components/juce_Desktop.cpp +++ b/src/gui/components/juce_Desktop.cpp @@ -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 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& 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& 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 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;) diff --git a/src/gui/components/juce_Desktop.h b/src/gui/components/juce_Desktop.h index 80e3d42f04..69f5309ff9 100644 --- a/src/gui/components/juce_Desktop.h +++ b/src/gui/components/juce_Desktop.h @@ -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 mouseListeners, focusListeners; Array desktopComponents; @@ -250,24 +261,12 @@ private: Array > monitorCoordsClipped, monitorCoordsUnclipped; + OwnedArray mouseSources; + Point lastFakeMouseMove; int mouseClickCounter; - bool mouseMovedSignificantlySincePressed; - - struct RecentMouseDown - { - Point position; - int64 time; - Component* component; - }; - - RecentMouseDown mouseDowns[4]; void incrementMouseClickCounter() throw(); - void registerMouseDown (const Point& position, int64 time, Component* component) throw(); - void registerMouseDrag (const Point& position) throw(); - const Time getLastMouseDownTime() const throw(); - int getNumberOfMultipleClicks() const throw(); Component* kioskModeComponent; Rectangle kioskComponentOriginalBounds; diff --git a/src/gui/components/keyboard/juce_ModifierKeys.cpp b/src/gui/components/keyboard/juce_ModifierKeys.cpp index f4d3294de5..a6db2bfcae 100644 --- a/src/gui/components/keyboard/juce_ModifierKeys.cpp +++ b/src/gui/components/keyboard/juce_ModifierKeys.cpp @@ -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() diff --git a/src/gui/components/keyboard/juce_ModifierKeys.h b/src/gui/components/keyboard/juce_ModifierKeys.h index 47d4418d73..5b0722ba08 100644 --- a/src/gui/components/keyboard/juce_ModifierKeys.h +++ b/src/gui/components/keyboard/juce_ModifierKeys.h @@ -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(); }; diff --git a/src/gui/components/mouse/juce_MouseEvent.cpp b/src/gui/components/mouse/juce_MouseEvent.cpp index 9f7461d5e4..9777702b3a 100644 --- a/src/gui/components/mouse/juce_MouseEvent.cpp +++ b/src/gui/components/mouse/juce_MouseEvent.cpp @@ -32,7 +32,8 @@ BEGIN_JUCE_NAMESPACE //============================================================================== -MouseEvent::MouseEvent (const Point& position, +MouseEvent::MouseEvent (MouseInputSource& source_, + const Point& position, const ModifierKeys& mods_, Component* const originator, const Time& eventTime_, @@ -46,6 +47,7 @@ MouseEvent::MouseEvent (const Point& 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& 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 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 (x, y)), - mods, - originalComponent, - eventTime, - eventComponent->relativePositionToOtherComponent (otherComponent, mouseDownPos), - mouseDownTime, - numberOfClicks, - wasMovedSinceMouseDown); -} - //============================================================================== static int doubleClickTimeOutMs = 400; diff --git a/src/gui/components/mouse/juce_MouseEvent.h b/src/gui/components/mouse/juce_MouseEvent.h index acc6153119..399b031dd8 100644 --- a/src/gui/components/mouse/juce_MouseEvent.h +++ b/src/gui/components/mouse/juce_MouseEvent.h @@ -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& position, + MouseEvent (MouseInputSource& source, + const Point& 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 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 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& newPosition) const throw(); + //============================================================================== /** Changes the application-wide setting for the double-click time limit. @@ -294,10 +307,12 @@ public: juce_UseDebuggingNewOperator private: - Point mouseDownPos; - Time mouseDownTime; - int numberOfClicks; - bool wasMovedSinceMouseDown; + const Point mouseDownPos; + const Time mouseDownTime; + const int numberOfClicks; + const bool wasMovedSinceMouseDown; + + MouseEvent& operator= (const MouseEvent&); }; diff --git a/src/gui/components/mouse/juce_MouseHoverDetector.cpp b/src/gui/components/mouse/juce_MouseHoverDetector.cpp index c9ed5c8345..ebe3f0dd32 100644 --- a/src/gui/components/mouse/juce_MouseHoverDetector.cpp +++ b/src/gui/components/mouse/juce_MouseHoverDetector.cpp @@ -29,6 +29,7 @@ BEGIN_JUCE_NAMESPACE #include "../juce_Component.h" #include "juce_MouseHoverDetector.h" +#include "juce_MouseEvent.h" //============================================================================== diff --git a/src/gui/components/mouse/juce_MouseInputSource.cpp b/src/gui/components/mouse/juce_MouseInputSource.cpp new file mode 100644 index 0000000000..c5223999bf --- /dev/null +++ b/src/gui/components/mouse/juce_MouseInputSource.cpp @@ -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 (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& screenPos) + { + ComponentPeer* const peer = getPeer(); + + if (peer != 0) + { + Component* const comp = peer->getComponent(); + const Point 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& 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& screenPos, const int64 time) + { + Component* current = getComponentUnderMouse(); + + if (newComponent != current) + { + ScopedPointer 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& screenPos, const int64 time) + { + ModifierKeys::updateCurrentModifiers(); + + if (newPeer != lastPeer) + { + setComponentUnderMouse (0, screenPos, time); + lastPeer = newPeer; + setComponentUnderMouse (findComponentAt (screenPos), screenPos, time); + } + } + + void setScreenPos (const Point& 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 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& positionWithinPeer, const int64 time, const ModifierKeys& newMods) + { + jassert (newPeer != 0); + lastTime = time; + const Point 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& positionWithinPeer, int64 time, float x, float y) + { + jassert (peer != 0); + lastTime = time; + const Point 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 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 lastScreenPos; + ModifierKeys buttonState; + +private: + MouseInputSource& source; + ScopedPointer componentUnderMouse; + ComponentPeer* lastPeer; + + struct RecentMouseDown + { + Point position; + int64 time; + Component* component; + }; + + RecentMouseDown mouseDowns[4]; + bool mouseMovedSignificantlySincePressed; + int64 lastTime; + + void registerMouseDown (const Point& 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& 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 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 MouseInputSource::getLastMouseDownPosition() const throw() { return pimpl->getLastMouseDownPosition(); } +bool MouseInputSource::hasMouseMovedSignificantlySincePressed() const throw() { return pimpl->hasMouseMovedSignificantlySincePressed(); } + +void MouseInputSource::handleEvent (ComponentPeer* peer, const Point& positionWithinPeer, const int64 time, const ModifierKeys& mods) +{ + pimpl->handleEvent (peer, positionWithinPeer, time, mods.withOnlyMouseButtons()); +} + +void MouseInputSource::handleWheel (ComponentPeer* const peer, const Point& positionWithinPeer, const int64 time, const float x, const float y) +{ + pimpl->handleWheel (peer, positionWithinPeer, time, x, y); +} + + +END_JUCE_NAMESPACE diff --git a/src/gui/components/mouse/juce_MouseInputSource.h b/src/gui/components/mouse/juce_MouseInputSource.h new file mode 100644 index 0000000000..b53373eac2 --- /dev/null +++ b/src/gui/components/mouse/juce_MouseInputSource.h @@ -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 getScreenPosition() const; + const ModifierKeys getCurrentModifiers() const; + Component* getComponentUnderMouse() const; + void triggerFakeMove() const; + int getNumberOfMultipleClicks() const throw(); + const Time getLastMouseDownTime() const throw(); + const Point getLastMouseDownPosition() const throw(); + bool hasMouseMovedSignificantlySincePressed() const throw(); + + //============================================================================== + juce_UseDebuggingNewOperator + + void handleEvent (ComponentPeer* peer, const Point& positionWithinPeer, int64 time, const ModifierKeys& mods); + void handleWheel (ComponentPeer* peer, const Point& positionWithinPeer, int64 time, float x, float y); + +private: + friend class MouseInputSourceInternal; + ScopedPointer pimpl; + + friend class Desktop; + friend class ComponentPeer; + + MouseInputSource (const MouseInputSource&); + MouseInputSource& operator= (const MouseInputSource&); +}; + + +#endif // __JUCE_MOUSEEVENT_JUCEHEADER__ diff --git a/src/gui/components/mouse/juce_MouseListener.h b/src/gui/components/mouse/juce_MouseListener.h index 6cfb8e7821..97ea26f16e 100644 --- a/src/gui/components/mouse/juce_MouseListener.h +++ b/src/gui/components/mouse/juce_MouseListener.h @@ -26,8 +26,7 @@ #ifndef __JUCE_MOUSELISTENER_JUCEHEADER__ #define __JUCE_MOUSELISTENER_JUCEHEADER__ -#include "juce_MouseEvent.h" - +class MouseEvent; //============================================================================== /** diff --git a/src/gui/components/special/juce_ActiveXControlComponent.h b/src/gui/components/special/juce_ActiveXControlComponent.h index 01709c05fc..fdfe3de490 100644 --- a/src/gui/components/special/juce_ActiveXControlComponent.h +++ b/src/gui/components/special/juce_ActiveXControlComponent.h @@ -116,6 +116,7 @@ public: juce_UseDebuggingNewOperator private: + class ActiveXControlData; friend class ActiveXControlData; void* control; bool mouseEventsAllowed; diff --git a/src/gui/components/special/juce_MagnifierComponent.cpp b/src/gui/components/special/juce_MagnifierComponent.cpp index 01336dc8cc..78a120c513 100644 --- a/src/gui/components/special/juce_MagnifierComponent.cpp +++ b/src/gui/components/special/juce_MagnifierComponent.cpp @@ -110,10 +110,10 @@ public: roundToInt (p.getY() / zoom)); } - bool contains (int x, int y, bool) const + bool contains (const Point& 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 (scaleInt (e.x), scaleInt (e.y)), e.eventTime.toMilliseconds()); + mouseSource.handleEvent (peer, Point (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 (scaleInt (e.x), scaleInt (e.y)), e.eventTime.toMilliseconds()); + passOnMouseEventToPeer (e); } void MagnifierComponent::mouseDrag (const MouseEvent& e) { - if (peer != 0) - peer->handleMouseDrag (Point (scaleInt (e.x), scaleInt (e.y)), e.eventTime.toMilliseconds()); + passOnMouseEventToPeer (e); } void MagnifierComponent::mouseMove (const MouseEvent& e) { - if (peer != 0) - peer->handleMouseMove (Point (scaleInt (e.x), scaleInt (e.y)), e.eventTime.toMilliseconds()); + passOnMouseEventToPeer (e); } void MagnifierComponent::mouseEnter (const MouseEvent& e) { - if (peer != 0) - peer->handleMouseEnter (Point (scaleInt (e.x), scaleInt (e.y)), e.eventTime.toMilliseconds()); + passOnMouseEventToPeer (e); } void MagnifierComponent::mouseExit (const MouseEvent& e) { - if (peer != 0) - peer->handleMouseExit (Point (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 (scaleInt (e.x), scaleInt (e.y)), e.eventTime.toMilliseconds(), + ix * 256.0f, iy * 256.0f); else Component::mouseWheelMove (e, ix, iy); } diff --git a/src/gui/components/special/juce_MagnifierComponent.h b/src/gui/components/special/juce_MagnifierComponent.h index a1f4cdf196..21d572e620 100644 --- a/src/gui/components/special/juce_MagnifierComponent.h +++ b/src/gui/components/special/juce_MagnifierComponent.h @@ -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&); diff --git a/src/gui/components/windows/juce_ComponentPeer.cpp b/src/gui/components/windows/juce_ComponentPeer.cpp index d22aa6d64c..4a4a66ef8b 100644 --- a/src/gui/components/windows/juce_ComponentPeer.cpp +++ b/src/gui/components/windows/juce_ComponentPeer.cpp @@ -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& position, const int64 time) +void ComponentPeer::handleMouseEvent (const Point& 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 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 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& position, const int64 time) +void ComponentPeer::handleMouseWheel (const Point& 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 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 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 relPos (component->relativePositionToOtherComponent (Component::componentUnderMouse, position)); - Component::componentUnderMouse->internalMouseMove (relPos.getX(), relPos.getY(), time); - } -} - -void ComponentPeer::handleMouseDown (const Point& position, const int64 time) -{ - Desktop::getInstance().incrementMouseClickCounter(); - updateCurrentModifiers(); - - if (ModifierKeys::getCurrentModifiers().getNumMouseButtonsDown() == 1) - { - Component::componentUnderMouse = component->getComponentAt (position); - - if (Component::componentUnderMouse != 0) - { - const Point relPos (component->relativePositionToOtherComponent (Component::componentUnderMouse, position)); - Component::componentUnderMouse->internalMouseDown (relPos.getX(), relPos.getY(), time); - } - } -} - -void ComponentPeer::handleMouseDrag (const Point& position, const int64 time) -{ - updateCurrentModifiers(); - - if (Component::componentUnderMouse != 0) - { - const Point relPos (component->relativePositionToOtherComponent (Component::componentUnderMouse, position)); - Component::componentUnderMouse->internalMouseDrag (relPos.getX(), relPos.getY(), time); - } -} - -void ComponentPeer::handleMouseUp (const int oldModifiers, const Point& 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 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 relPos (component->relativePositionToOtherComponent (Component::componentUnderMouse, position)); - Component::componentUnderMouse->internalMouseEnter (relPos.getX(), relPos.getY(), time); - } - } - else - { - if (Component::componentUnderMouse != 0) - { - const Point relPos (component->relativePositionToOtherComponent (Component::componentUnderMouse, position)); - Component::componentUnderMouse->internalMouseUp (oldModifiers, relPos.getX(), relPos.getY(), time); - } - } - } -} - -void ComponentPeer::handleMouseExit (const Point& position, const int64 time) -{ - jassert (component->isValidComponent()); - updateCurrentModifiers(); - - if (Component::componentUnderMouse != 0) - { - const Point 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 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 (message.intParameter2, message.intParameter3), - Time::currentTimeMillis()); - } + Desktop::getInstance().getMainMouseSource().handleWheel (this, positionWithinPeer, time, x, y); } //============================================================================== diff --git a/src/gui/components/windows/juce_ComponentPeer.h b/src/gui/components/windows/juce_ComponentPeer.h index 76240225e6..18f0bf79c3 100644 --- a/src/gui/components/windows/juce_ComponentPeer.h +++ b/src/gui/components/windows/juce_ComponentPeer.h @@ -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& 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& position, const int64 time); - void handleMouseMove (const Point& position, const int64 time); - void handleMouseDown (const Point& position, const int64 time); - void handleMouseDrag (const Point& position, const int64 time); - void handleMouseUp (const int oldModifiers, const Point& position, const int64 time); - void handleMouseExit (const Point& 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& positionWithinPeer, const ModifierKeys& newMods, const int64 time); + void handleMouseWheel (const Point& 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; diff --git a/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp b/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp index e050cf4024..281da9effe 100644 --- a/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp +++ b/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp @@ -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; diff --git a/src/io/streams/juce_OutputStream.cpp b/src/io/streams/juce_OutputStream.cpp index 974807f4d2..1d7b96f3e4 100644 --- a/src/io/streams/juce_OutputStream.cpp +++ b/src/io/streams/juce_OutputStream.cpp @@ -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; diff --git a/src/io/streams/juce_OutputStream.h b/src/io/streams/juce_OutputStream.h index 87f2978748..5ee7d5f9dc 100644 --- a/src/io/streams/juce_OutputStream.h +++ b/src/io/streams/juce_OutputStream.h @@ -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); diff --git a/src/native/juce_mac_NativeCode.mm b/src/native/juce_mac_NativeCode.mm index 1cd29699df..4076acfa0b 100644 --- a/src/native/juce_mac_NativeCode.mm +++ b/src/native/juce_mac_NativeCode.mm @@ -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" diff --git a/src/native/linux/juce_linux_Windowing.cpp b/src/native/linux/juce_linux_Windowing.cpp index 3022b997c6..9687f6732a 100644 --- a/src/native/linux/juce_linux_Windowing.cpp +++ b/src/native/linux/juce_linux_Windowing.cpp @@ -120,33 +120,6 @@ enum MouseButtons WheelDown = 5 }; -static const Point 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 (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& 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 (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 (buttonPressEvent->x, buttonPressEvent->y), - getEventTime (buttonPressEvent->time)); - } - else if (wheelUpMsg || wheelDownMsg) - { - handleMouseWheel (0, wheelDownMsg ? -84 : 84, + + handleMouseEvent (Point (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 (buttonRelEvent->x, buttonRelEvent->y), - getEventTime (buttonRelEvent->time)); + handleMouseEvent (Point (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 mousePos (Desktop::getMousePosition()); + const Point 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 (enterEvent->x, enterEvent->y), getEventTime (enterEvent->time)); - - entered = true; + handleMouseEvent (Point (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 (leaveEvent->x, leaveEvent->y), getEventTime (leaveEvent->time)); - - entered = false; + handleMouseEvent (Point (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 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 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 (x, y); } void Desktop::setMousePosition (const Point& newPosition) diff --git a/src/native/mac/juce_iphone_UIViewComponentPeer.mm b/src/native/mac/juce_iphone_UIViewComponentPeer.mm index 9ecce2a17e..466e1dcb17 100644 --- a/src/native/mac/juce_iphone_UIViewComponentPeer.mm +++ b/src/native/mac/juce_iphone_UIViewComponentPeer.mm @@ -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& 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 juce_lastMousePos; { CGPoint p = [[t objectAtIndex: 0] locationInView: self]; const JUCE_NAMESPACE::Point 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 juce_lastMousePos; const JUCE_NAMESPACE::Point 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 juce_lastMousePos; const JUCE_NAMESPACE::Point 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& 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]; diff --git a/src/native/mac/juce_mac_NSViewComponentPeer.mm b/src/native/mac/juce_mac_NSViewComponentPeer.mm index 2458220260..2894a0c4f2 100644 --- a/src/native/mac/juce_mac_NSViewComponentPeer.mm +++ b/src/native/mac/juce_mac_NSViewComponentPeer.mm @@ -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& 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& 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() diff --git a/src/native/windows/juce_win32_ActiveXComponent.cpp b/src/native/windows/juce_win32_ActiveXComponent.cpp index bb739fc7d7..61ad53c2ab 100644 --- a/src/native/windows/juce_win32_ActiveXComponent.cpp +++ b/src/native/windows/juce_win32_ActiveXComponent.cpp @@ -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 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 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 (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; diff --git a/src/native/windows/juce_win32_Windowing.cpp b/src/native/windows/juce_win32_Windowing.cpp index 612739b098..01664df020 100644 --- a/src/native/windows/juce_win32_Windowing.cpp +++ b/src/native/windows/juce_win32_Windowing.cpp @@ -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& 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& 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& 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 (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 (x, y), mouseEventTime); - } - } - } + if (! contains (position, false)) + return; } - else - { - const uint32 now = Time::getMillisecondCounter(); - if (now > lastMouseTime + 1000 / maxMouseMovesPerSecond) - { - lastMouseTime = now; - handleMouseDrag (Point (x, y), mouseEventTime); - } - } + doMouseEvent (position); } - void doMouseDown (const int x, const int y, const WPARAM wParam) + void doMouseDown (const Point& 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 (x, y), getMouseEventTime()); + doMouseEvent (position); } - void doMouseUp (const int x, const int y, const WPARAM wParam) + void doMouseUp (const Point& 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 (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 (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& 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 getPointFromLParam (LPARAM lParam) throw() + { + return Point (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam)); + } + + const Point getCurrentMousePos() throw() + { + RECT wr; + GetWindowRect (hwnd, &wr); + const DWORD mp = GetMessagePos(); + + return Point (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(), ModifierKeys::getCurrentModifiersRealtime(), component, - getMouseEventTime(), Point(), 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(), eventMods, component, getMouseEventTime(), + Point(), 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) {