| @@ -818,14 +818,10 @@ void MidiKeyboardComponent::timerCallback() | |||
| if (shouldCheckMousePos) | |||
| { | |||
| const OwnedArray<MouseInputSource>& mouseSources = Desktop::getInstance().getMouseSources(); | |||
| const Array<MouseInputSource>& mouseSources = Desktop::getInstance().getMouseSources(); | |||
| for (MouseInputSource** i = mouseSources.begin(), ** const e = mouseSources.end(); i != e; ++i) | |||
| { | |||
| const MouseInputSource& source = **i; | |||
| updateNoteUnderMouse (getLocalPoint (nullptr, source.getScreenPosition()), | |||
| source.isDragging(), source.getIndex()); | |||
| } | |||
| for (MouseInputSource* mi = mouseSources.begin(), * const e = mouseSources.end(); mi != e; ++mi) | |||
| updateNoteUnderMouse (getLocalPoint (nullptr, mi->getScreenPosition()), mi->isDragging(), mi->getIndex()); | |||
| } | |||
| } | |||
| @@ -165,29 +165,29 @@ private: | |||
| }; | |||
| //============================================================================== | |||
| GZIPDecompressorInputStream::GZIPDecompressorInputStream (InputStream* const sourceStream_, | |||
| GZIPDecompressorInputStream::GZIPDecompressorInputStream (InputStream* const source, | |||
| const bool deleteSourceWhenDestroyed, | |||
| const bool noWrap_, | |||
| const int64 uncompressedStreamLength_) | |||
| : sourceStream (sourceStream_, deleteSourceWhenDestroyed), | |||
| : sourceStream (source, deleteSourceWhenDestroyed), | |||
| uncompressedStreamLength (uncompressedStreamLength_), | |||
| noWrap (noWrap_), | |||
| isEof (false), | |||
| activeBufferSize (0), | |||
| originalSourcePos (sourceStream_->getPosition()), | |||
| originalSourcePos (source->getPosition()), | |||
| currentPos (0), | |||
| buffer ((size_t) GZIPDecompressHelper::gzipDecompBufferSize), | |||
| helper (new GZIPDecompressHelper (noWrap_)) | |||
| { | |||
| } | |||
| GZIPDecompressorInputStream::GZIPDecompressorInputStream (InputStream& sourceStream_) | |||
| : sourceStream (&sourceStream_, false), | |||
| GZIPDecompressorInputStream::GZIPDecompressorInputStream (InputStream& source) | |||
| : sourceStream (&source, false), | |||
| uncompressedStreamLength (-1), | |||
| noWrap (false), | |||
| isEof (false), | |||
| activeBufferSize (0), | |||
| originalSourcePos (sourceStream_.getPosition()), | |||
| originalSourcePos (source.getPosition()), | |||
| currentPos (0), | |||
| buffer ((size_t) GZIPDecompressHelper::gzipDecompBufferSize), | |||
| helper (new GZIPDecompressHelper (false)) | |||
| @@ -2310,7 +2310,7 @@ void Component::removeMouseListener (MouseListener* const listenerToRemove) | |||
| } | |||
| //============================================================================== | |||
| void Component::internalMouseEnter (MouseInputSource& source, Point<int> relativePos, Time time) | |||
| void Component::internalMouseEnter (MouseInputSource source, Point<int> relativePos, Time time) | |||
| { | |||
| if (isCurrentlyBlockedByAnotherModalComponent()) | |||
| { | |||
| @@ -2336,7 +2336,7 @@ void Component::internalMouseEnter (MouseInputSource& source, Point<int> relativ | |||
| MouseListenerList::sendMouseEvent (*this, checker, &MouseListener::mouseEnter, me); | |||
| } | |||
| void Component::internalMouseExit (MouseInputSource& source, Point<int> relativePos, Time time) | |||
| void Component::internalMouseExit (MouseInputSource source, Point<int> relativePos, Time time) | |||
| { | |||
| if (flags.repaintOnMouseActivityFlag) | |||
| repaint(); | |||
| @@ -2356,7 +2356,7 @@ void Component::internalMouseExit (MouseInputSource& source, Point<int> relative | |||
| MouseListenerList::sendMouseEvent (*this, checker, &MouseListener::mouseExit, me); | |||
| } | |||
| void Component::internalMouseDown (MouseInputSource& source, Point<int> relativePos, Time time) | |||
| void Component::internalMouseDown (MouseInputSource source, Point<int> relativePos, Time time) | |||
| { | |||
| Desktop& desktop = Desktop::getInstance(); | |||
| BailOutChecker checker (this); | |||
| @@ -2420,7 +2420,7 @@ void Component::internalMouseDown (MouseInputSource& source, Point<int> relative | |||
| MouseListenerList::sendMouseEvent (*this, checker, &MouseListener::mouseDown, me); | |||
| } | |||
| void Component::internalMouseUp (MouseInputSource& source, Point<int> relativePos, | |||
| void Component::internalMouseUp (MouseInputSource source, Point<int> relativePos, | |||
| Time time, const ModifierKeys oldModifiers) | |||
| { | |||
| if (flags.mouseDownWasBlocked && isCurrentlyBlockedByAnotherModalComponent()) | |||
| @@ -2463,7 +2463,7 @@ void Component::internalMouseUp (MouseInputSource& source, Point<int> relativePo | |||
| } | |||
| } | |||
| void Component::internalMouseDrag (MouseInputSource& source, Point<int> relativePos, Time time) | |||
| void Component::internalMouseDrag (MouseInputSource source, Point<int> relativePos, Time time) | |||
| { | |||
| if (! isCurrentlyBlockedByAnotherModalComponent()) | |||
| { | |||
| @@ -2486,7 +2486,7 @@ void Component::internalMouseDrag (MouseInputSource& source, Point<int> relative | |||
| } | |||
| } | |||
| void Component::internalMouseMove (MouseInputSource& source, Point<int> relativePos, Time time) | |||
| void Component::internalMouseMove (MouseInputSource source, Point<int> relativePos, Time time) | |||
| { | |||
| Desktop& desktop = Desktop::getInstance(); | |||
| @@ -2512,7 +2512,7 @@ void Component::internalMouseMove (MouseInputSource& source, Point<int> relative | |||
| } | |||
| } | |||
| void Component::internalMouseWheel (MouseInputSource& source, Point<int> relativePos, | |||
| void Component::internalMouseWheel (MouseInputSource source, Point<int> relativePos, | |||
| Time time, const MouseWheelDetails& wheel) | |||
| { | |||
| Desktop& desktop = Desktop::getInstance(); | |||
| @@ -2540,7 +2540,7 @@ void Component::internalMouseWheel (MouseInputSource& source, Point<int> relativ | |||
| } | |||
| } | |||
| void Component::internalMagnifyGesture (MouseInputSource& source, Point<int> relativePos, | |||
| void Component::internalMagnifyGesture (MouseInputSource source, Point<int> relativePos, | |||
| Time time, float amount) | |||
| { | |||
| if (! isCurrentlyBlockedByAnotherModalComponent()) | |||
| @@ -2554,7 +2554,7 @@ void Component::internalMagnifyGesture (MouseInputSource& source, Point<int> rel | |||
| void Component::sendFakeMouseMove() const | |||
| { | |||
| MouseInputSource& mainMouse = Desktop::getInstance().getMainMouseSource(); | |||
| MouseInputSource mainMouse = Desktop::getInstance().getMainMouseSource(); | |||
| if (! mainMouse.isDragging()) | |||
| mainMouse.triggerFakeMove(); | |||
| @@ -2883,17 +2883,15 @@ void Component::sendEnablementChangeMessage() | |||
| //============================================================================== | |||
| bool Component::isMouseOver (const bool includeChildren) const | |||
| { | |||
| const OwnedArray<MouseInputSource>& mouseSources = Desktop::getInstance().getMouseSources(); | |||
| const Array<MouseInputSource>& mouseSources = Desktop::getInstance().getMouseSources(); | |||
| for (MouseInputSource** i = mouseSources.begin(), ** const e = mouseSources.end(); i != e; ++i) | |||
| for (MouseInputSource* mi = mouseSources.begin(), * const e = mouseSources.end(); mi != e; ++mi) | |||
| { | |||
| const MouseInputSource& mi = **i; | |||
| Component* const c = mi.getComponentUnderMouse(); | |||
| Component* const c = mi->getComponentUnderMouse(); | |||
| if ((c == this || (includeChildren && isParentOf (c))) | |||
| && c->reallyContains (c->getLocalPoint (nullptr, mi.getScreenPosition()), false) | |||
| && (mi.isMouse() || mi.isDragging())) | |||
| && c->reallyContains (c->getLocalPoint (nullptr, mi->getScreenPosition()), false) | |||
| && (mi->isMouse() || mi->isDragging())) | |||
| return true; | |||
| } | |||
| @@ -2902,10 +2900,10 @@ bool Component::isMouseOver (const bool includeChildren) const | |||
| bool Component::isMouseButtonDown() const | |||
| { | |||
| const OwnedArray<MouseInputSource>& mouseSources = Desktop::getInstance().getMouseSources(); | |||
| const Array<MouseInputSource>& mouseSources = Desktop::getInstance().getMouseSources(); | |||
| for (MouseInputSource** i = mouseSources.begin(), ** const e = mouseSources.end(); i != e; ++i) | |||
| if ((*i)->isDragging() && (*i)->getComponentUnderMouse() == this) | |||
| for (MouseInputSource* mi = mouseSources.begin(), * const e = mouseSources.end(); mi != e; ++mi) | |||
| if (mi->isDragging() && mi->getComponentUnderMouse() == this) | |||
| return true; | |||
| return false; | |||
| @@ -2913,11 +2911,11 @@ bool Component::isMouseButtonDown() const | |||
| bool Component::isMouseOverOrDragging() const | |||
| { | |||
| const OwnedArray<MouseInputSource>& mouseSources = Desktop::getInstance().getMouseSources(); | |||
| const Array<MouseInputSource>& mouseSources = Desktop::getInstance().getMouseSources(); | |||
| for (MouseInputSource** i = mouseSources.begin(), ** const e = mouseSources.end(); i != e; ++i) | |||
| if ((*i)->getComponentUnderMouse() == this | |||
| && ((*i)->isMouse() || (*i)->isDragging())) | |||
| for (MouseInputSource* mi = mouseSources.begin(), * const e = mouseSources.end(); mi != e; ++mi) | |||
| if (mi->getComponentUnderMouse() == this | |||
| && (mi->isMouse() || mi->isDragging())) | |||
| return true; | |||
| return false; | |||
| @@ -2280,14 +2280,14 @@ private: | |||
| uint8 componentTransparency; | |||
| //============================================================================== | |||
| void internalMouseEnter (MouseInputSource&, Point<int>, Time); | |||
| void internalMouseExit (MouseInputSource&, Point<int>, Time); | |||
| void internalMouseDown (MouseInputSource&, Point<int>, Time); | |||
| void internalMouseUp (MouseInputSource&, Point<int>, Time, const ModifierKeys oldModifiers); | |||
| void internalMouseDrag (MouseInputSource&, Point<int>, Time); | |||
| void internalMouseMove (MouseInputSource&, Point<int>, Time); | |||
| void internalMouseWheel (MouseInputSource&, Point<int>, Time, const MouseWheelDetails&); | |||
| void internalMagnifyGesture (MouseInputSource&, Point<int>, Time, float); | |||
| void internalMouseEnter (MouseInputSource, Point<int>, Time); | |||
| void internalMouseExit (MouseInputSource, Point<int>, Time); | |||
| void internalMouseDown (MouseInputSource, Point<int>, Time); | |||
| void internalMouseUp (MouseInputSource, Point<int>, Time, const ModifierKeys oldModifiers); | |||
| void internalMouseDrag (MouseInputSource, Point<int>, Time); | |||
| void internalMouseMove (MouseInputSource, Point<int>, Time); | |||
| void internalMouseWheel (MouseInputSource, Point<int>, Time, const MouseWheelDetails&); | |||
| void internalMagnifyGesture (MouseInputSource, Point<int>, Time, float); | |||
| void internalBroughtToFront(); | |||
| void internalFocusGain (const FocusChangeType, const WeakReference<Component>&); | |||
| void internalFocusGain (const FocusChangeType); | |||
| @@ -23,13 +23,13 @@ | |||
| */ | |||
| Desktop::Desktop() | |||
| : mouseClickCounter (0), mouseWheelCounter (0), | |||
| : mouseSources (new MouseInputSource::SourceList()), | |||
| mouseClickCounter (0), mouseWheelCounter (0), | |||
| kioskModeComponent (nullptr), | |||
| allowedOrientations (allOrientations), | |||
| masterScaleFactor ((float) getDefaultMasterScale()) | |||
| { | |||
| displays = new Displays (*this); | |||
| addMouseInputSource(); | |||
| } | |||
| Desktop::~Desktop() | |||
| @@ -164,113 +164,18 @@ int Desktop::getMouseWheelMoveCounter() const noexcept { return mouseWheelC | |||
| void Desktop::incrementMouseClickCounter() noexcept { ++mouseClickCounter; } | |||
| void Desktop::incrementMouseWheelCounter() noexcept { ++mouseWheelCounter; } | |||
| int Desktop::getNumDraggingMouseSources() const noexcept | |||
| { | |||
| int num = 0; | |||
| for (int i = mouseSources.size(); --i >= 0;) | |||
| if (mouseSources.getUnchecked(i)->isDragging()) | |||
| ++num; | |||
| return num; | |||
| } | |||
| MouseInputSource* Desktop::getDraggingMouseSource (int index) const noexcept | |||
| { | |||
| int num = 0; | |||
| for (int i = mouseSources.size(); --i >= 0;) | |||
| { | |||
| MouseInputSource* const mi = mouseSources.getUnchecked(i); | |||
| if (mi->isDragging()) | |||
| { | |||
| if (index == num) | |||
| return mi; | |||
| ++num; | |||
| } | |||
| } | |||
| return nullptr; | |||
| } | |||
| MouseInputSource* Desktop::getOrCreateMouseInputSource (int touchIndex) | |||
| { | |||
| jassert (touchIndex >= 0 && touchIndex < 100); // sanity-check on number of fingers | |||
| for (;;) | |||
| { | |||
| if (MouseInputSource* mouse = getMouseSource (touchIndex)) | |||
| return mouse; | |||
| if (! addMouseInputSource()) | |||
| { | |||
| jassertfalse; // not enough mouse sources! | |||
| return nullptr; | |||
| } | |||
| } | |||
| } | |||
| //============================================================================== | |||
| class MouseDragAutoRepeater : public Timer | |||
| { | |||
| public: | |||
| MouseDragAutoRepeater() {} | |||
| void timerCallback() override | |||
| { | |||
| Desktop& desktop = Desktop::getInstance(); | |||
| int numMiceDown = 0; | |||
| const OwnedArray<MouseInputSource>& mouseSources = desktop.getMouseSources(); | |||
| for (MouseInputSource** i = mouseSources.begin(), ** const e = mouseSources.end(); i != e; ++i) | |||
| { | |||
| if ((*i)->isDragging()) | |||
| { | |||
| (*i)->triggerFakeMove(); | |||
| ++numMiceDown; | |||
| } | |||
| } | |||
| if (numMiceDown == 0) | |||
| desktop.beginDragAutoRepeat (0); | |||
| } | |||
| private: | |||
| JUCE_DECLARE_NON_COPYABLE (MouseDragAutoRepeater) | |||
| }; | |||
| void Desktop::beginDragAutoRepeat (const int interval) | |||
| { | |||
| if (interval > 0) | |||
| { | |||
| if (dragRepeater == nullptr) | |||
| dragRepeater = new MouseDragAutoRepeater(); | |||
| if (dragRepeater->getTimerInterval() != interval) | |||
| dragRepeater->startTimer (interval); | |||
| } | |||
| else | |||
| { | |||
| dragRepeater = nullptr; | |||
| } | |||
| } | |||
| const Array<MouseInputSource>& Desktop::getMouseSources() const noexcept { return mouseSources->sourceArray; } | |||
| int Desktop::getNumMouseSources() const noexcept { return mouseSources->sources.size(); } | |||
| int Desktop::getNumDraggingMouseSources() const noexcept { return mouseSources->getNumDraggingMouseSources(); } | |||
| MouseInputSource* Desktop::getMouseSource (int index) const noexcept { return mouseSources->getMouseSource (index); } | |||
| MouseInputSource* Desktop::getDraggingMouseSource (int index) const noexcept { return mouseSources->getDraggingMouseSource (index); } | |||
| MouseInputSource Desktop::getMainMouseSource() const noexcept { return MouseInputSource (mouseSources->sources.getUnchecked(0)); } | |||
| void Desktop::beginDragAutoRepeat (int interval) { mouseSources->beginDragAutoRepeat (interval); } | |||
| //============================================================================== | |||
| void Desktop::addFocusChangeListener (FocusChangeListener* const listener) | |||
| { | |||
| focusListeners.add (listener); | |||
| } | |||
| void Desktop::removeFocusChangeListener (FocusChangeListener* const listener) | |||
| { | |||
| focusListeners.remove (listener); | |||
| } | |||
| void Desktop::triggerFocusCallback() | |||
| { | |||
| triggerAsyncUpdate(); | |||
| } | |||
| void Desktop::addFocusChangeListener (FocusChangeListener* const listener) { focusListeners.add (listener); } | |||
| void Desktop::removeFocusChangeListener (FocusChangeListener* const listener) { focusListeners.remove (listener); } | |||
| void Desktop::triggerFocusCallback() { triggerAsyncUpdate(); } | |||
| void Desktop::handleAsyncUpdate() | |||
| { | |||
| @@ -225,14 +225,22 @@ public: | |||
| void setDefaultLookAndFeel (LookAndFeel* newDefaultLookAndFeel); | |||
| //============================================================================== | |||
| /** Provides access to the array of mouse sources, for iteration. | |||
| In a traditional single-mouse system, there might be only one MouseInputSource. On a | |||
| multi-touch system, there could be one input source per potential finger. The number | |||
| of mouse sources returned here may increase dynamically as the program runs. | |||
| To find out how many mouse events are currently happening, use getNumDraggingMouseSources(). | |||
| */ | |||
| const Array<MouseInputSource>& getMouseSources() const noexcept; | |||
| /** Returns the number of MouseInputSource objects the system has at its disposal. | |||
| In a traditional single-mouse system, there might be only one object. On a multi-touch | |||
| system, there could be one input source per potential finger. The number of mouse | |||
| sources returned here may increase dynamically as the program runs. | |||
| In a traditional single-mouse system, there might be only one MouseInputSource. On a | |||
| multi-touch system, there could be one input source per potential finger. The number | |||
| of mouse sources returned here may increase dynamically as the program runs. | |||
| To find out how many mouse events are currently happening, use getNumDraggingMouseSources(). | |||
| @see getMouseSource | |||
| */ | |||
| int getNumMouseSources() const noexcept { return mouseSources.size(); } | |||
| int getNumMouseSources() const noexcept; | |||
| /** Returns one of the system's MouseInputSource objects. | |||
| The index should be from 0 to getNumMouseSources() - 1. Out-of-range indexes will return | |||
| @@ -240,15 +248,12 @@ public: | |||
| In a traditional single-mouse system, there might be only one object. On a multi-touch | |||
| system, there could be one input source per potential finger. | |||
| */ | |||
| MouseInputSource* getMouseSource (int index) const noexcept { return mouseSources [index]; } | |||
| /** Provides access to the array of mouse sources, for iteration. */ | |||
| const OwnedArray<MouseInputSource>& getMouseSources() const { return mouseSources; } | |||
| MouseInputSource* getMouseSource (int index) const noexcept; | |||
| /** Returns the main mouse input device that the system is using. | |||
| @see getNumMouseSources() | |||
| */ | |||
| MouseInputSource& getMainMouseSource() const noexcept { return *mouseSources.getUnchecked(0); } | |||
| MouseInputSource getMainMouseSource() const noexcept; | |||
| /** Returns the number of mouse-sources that are currently being dragged. | |||
| In a traditional single-mouse system, this will be 0 or 1, depending on whether a | |||
| @@ -395,13 +400,11 @@ private: | |||
| friend class Component; | |||
| friend class ComponentPeer; | |||
| friend class MouseInputSource; | |||
| friend class MouseInputSourceInternal; | |||
| friend class DeletedAtShutdown; | |||
| friend class TopLevelWindowManager; | |||
| OwnedArray<MouseInputSource> mouseSources; | |||
| bool addMouseInputSource(); | |||
| ScopedPointer<MouseInputSource::SourceList> mouseSources; | |||
| ListenerList<MouseListener> mouseListeners; | |||
| ListenerList<FocusChangeListener> focusListeners; | |||
| @@ -418,8 +421,6 @@ private: | |||
| void incrementMouseClickCounter() noexcept; | |||
| void incrementMouseWheelCounter() noexcept; | |||
| ScopedPointer<Timer> dragRepeater; | |||
| ScopedPointer<LookAndFeel> defaultLookAndFeel; | |||
| WeakReference<LookAndFeel> currentLookAndFeel; | |||
| @@ -434,7 +435,6 @@ private: | |||
| void timerCallback() override; | |||
| void resetTimer(); | |||
| ListenerList<MouseListener>& getMouseListeners(); | |||
| MouseInputSource* getOrCreateMouseInputSource (int touchIndex); | |||
| void addDesktopComponent (Component*); | |||
| void removeDesktopComponent (Component*); | |||
| @@ -137,6 +137,7 @@ extern bool juce_areThereAnyAlwaysOnTopWindows(); | |||
| #include "components/juce_Component.cpp" | |||
| #include "components/juce_ComponentListener.cpp" | |||
| #include "mouse/juce_MouseInputSource.cpp" | |||
| #include "components/juce_Desktop.cpp" | |||
| #include "components/juce_ModalComponentManager.cpp" | |||
| #include "mouse/juce_ComponentDragger.cpp" | |||
| @@ -144,7 +145,6 @@ extern bool juce_areThereAnyAlwaysOnTopWindows(); | |||
| #include "mouse/juce_MouseCursor.cpp" | |||
| #include "mouse/juce_MouseEvent.cpp" | |||
| #include "mouse/juce_MouseInactivityDetector.cpp" | |||
| #include "mouse/juce_MouseInputSource.cpp" | |||
| #include "mouse/juce_MouseListener.cpp" | |||
| #include "keyboard/juce_CaretComponent.cpp" | |||
| #include "keyboard/juce_KeyboardFocusTraverser.cpp" | |||
| @@ -117,6 +117,7 @@ class ApplicationCommandManagerListener; | |||
| #include "mouse/juce_MouseCursor.h" | |||
| #include "mouse/juce_MouseListener.h" | |||
| #include "keyboard/juce_ModifierKeys.h" | |||
| #include "mouse/juce_MouseInputSource.h" | |||
| #include "mouse/juce_MouseEvent.h" | |||
| #include "keyboard/juce_KeyPress.h" | |||
| #include "keyboard/juce_KeyListener.h" | |||
| @@ -135,7 +136,6 @@ class ApplicationCommandManagerListener; | |||
| #include "mouse/juce_SelectedItemSet.h" | |||
| #include "mouse/juce_LassoComponent.h" | |||
| #include "mouse/juce_MouseInactivityDetector.h" | |||
| #include "mouse/juce_MouseInputSource.h" | |||
| #include "mouse/juce_TextDragAndDropTarget.h" | |||
| #include "mouse/juce_TooltipClient.h" | |||
| #include "keyboard/juce_CaretComponent.h" | |||
| @@ -504,12 +504,12 @@ public: | |||
| return activeMenuWindows; | |||
| } | |||
| MouseSourceState& getMouseState (MouseInputSource& source) | |||
| MouseSourceState& getMouseState (MouseInputSource source) | |||
| { | |||
| for (int i = mouseSourceStates.size(); --i >= 0;) | |||
| { | |||
| MouseSourceState& ms = *mouseSourceStates.getUnchecked(i); | |||
| if (&ms.source == &source) | |||
| if (ms.source == source) | |||
| return ms; | |||
| } | |||
| @@ -961,7 +961,7 @@ public: | |||
| class MouseSourceState : private Timer | |||
| { | |||
| public: | |||
| MouseSourceState (MenuWindow& w, MouseInputSource& s) | |||
| MouseSourceState (MenuWindow& w, MouseInputSource s) | |||
| : window (w), source (s), scrollAcceleration (1.0), | |||
| lastScrollTime (Time::getMillisecondCounter()), | |||
| lastMouseMoveTime (0), isDown (false) | |||
| @@ -989,7 +989,7 @@ public: | |||
| } | |||
| MenuWindow& window; | |||
| MouseInputSource& source; | |||
| MouseInputSource source; | |||
| private: | |||
| Point<int> lastMousePos; | |||
| @@ -22,7 +22,7 @@ | |||
| ============================================================================== | |||
| */ | |||
| MouseEvent::MouseEvent (MouseInputSource& inputSource, | |||
| MouseEvent::MouseEvent (MouseInputSource inputSource, | |||
| Point<int> position, | |||
| ModifierKeys modKeys, | |||
| Component* const eventComp, | |||
| @@ -56,7 +56,7 @@ 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 (MouseInputSource& source, | |||
| MouseEvent (MouseInputSource source, | |||
| Point<int> position, | |||
| ModifierKeys modifiers, | |||
| Component* eventComponent, | |||
| @@ -126,7 +126,7 @@ public: | |||
| const Time mouseDownTime; | |||
| /** The source device that generated this event. */ | |||
| MouseInputSource& source; | |||
| MouseInputSource source; | |||
| //============================================================================== | |||
| /** Returns the x coordinate of the last place that a mouse was pressed. | |||
| @@ -26,8 +26,8 @@ class MouseInputSourceInternal : private AsyncUpdater | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| MouseInputSourceInternal (MouseInputSource& s, const int i, const bool isMouse) | |||
| : index (i), isMouseDevice (isMouse), source (s), lastPeer (nullptr), | |||
| MouseInputSourceInternal (const int i, const bool isMouse) | |||
| : index (i), isMouseDevice (isMouse), lastPeer (nullptr), | |||
| isUnboundedMouseModeOn (false), isCursorVisibleUntilOffscreen (false), currentCursorHandle (nullptr), | |||
| mouseEventCounter (0), mouseMovedSignificantlySincePressed (false) | |||
| { | |||
| @@ -111,49 +111,49 @@ public: | |||
| void sendMouseEnter (Component& comp, Point<int> screenPos, Time time) | |||
| { | |||
| JUCE_MOUSE_EVENT_DBG ("enter") | |||
| comp.internalMouseEnter (source, screenPosToLocalPos (comp, screenPos), time); | |||
| comp.internalMouseEnter (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time); | |||
| } | |||
| void sendMouseExit (Component& comp, Point<int> screenPos, Time time) | |||
| { | |||
| JUCE_MOUSE_EVENT_DBG ("exit") | |||
| comp.internalMouseExit (source, screenPosToLocalPos (comp, screenPos), time); | |||
| comp.internalMouseExit (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time); | |||
| } | |||
| void sendMouseMove (Component& comp, Point<int> screenPos, Time time) | |||
| { | |||
| JUCE_MOUSE_EVENT_DBG ("move") | |||
| comp.internalMouseMove (source, screenPosToLocalPos (comp, screenPos), time); | |||
| comp.internalMouseMove (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time); | |||
| } | |||
| void sendMouseDown (Component& comp, Point<int> screenPos, Time time) | |||
| { | |||
| JUCE_MOUSE_EVENT_DBG ("down") | |||
| comp.internalMouseDown (source, screenPosToLocalPos (comp, screenPos), time); | |||
| comp.internalMouseDown (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time); | |||
| } | |||
| void sendMouseDrag (Component& comp, Point<int> screenPos, Time time) | |||
| { | |||
| JUCE_MOUSE_EVENT_DBG ("drag") | |||
| comp.internalMouseDrag (source, screenPosToLocalPos (comp, screenPos), time); | |||
| comp.internalMouseDrag (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time); | |||
| } | |||
| void sendMouseUp (Component& comp, Point<int> screenPos, Time time, const ModifierKeys oldMods) | |||
| { | |||
| JUCE_MOUSE_EVENT_DBG ("up") | |||
| comp.internalMouseUp (source, screenPosToLocalPos (comp, screenPos), time, oldMods); | |||
| comp.internalMouseUp (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time, oldMods); | |||
| } | |||
| void sendMouseWheel (Component& comp, Point<int> screenPos, Time time, const MouseWheelDetails& wheel) | |||
| { | |||
| JUCE_MOUSE_EVENT_DBG ("wheel") | |||
| comp.internalMouseWheel (source, screenPosToLocalPos (comp, screenPos), time, wheel); | |||
| comp.internalMouseWheel (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time, wheel); | |||
| } | |||
| void sendMagnifyGesture (Component& comp, Point<int> screenPos, Time time, const float amount) | |||
| { | |||
| JUCE_MOUSE_EVENT_DBG ("magnify") | |||
| comp.internalMagnifyGesture (source, screenPosToLocalPos (comp, screenPos), time, amount); | |||
| comp.internalMagnifyGesture (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time, amount); | |||
| } | |||
| //============================================================================== | |||
| @@ -464,7 +464,6 @@ public: | |||
| ModifierKeys buttonState; | |||
| private: | |||
| MouseInputSource& source; | |||
| WeakReference<Component> componentUnderMouse; | |||
| ComponentPeer* lastPeer; | |||
| @@ -524,13 +523,16 @@ private: | |||
| }; | |||
| //============================================================================== | |||
| MouseInputSource::MouseInputSource (const int index, const bool isMouseDevice) | |||
| MouseInputSource::MouseInputSource (MouseInputSourceInternal* s) noexcept : pimpl (s) {} | |||
| MouseInputSource::MouseInputSource (const MouseInputSource& other) noexcept : pimpl (other.pimpl) {} | |||
| MouseInputSource::~MouseInputSource() noexcept {} | |||
| MouseInputSource& MouseInputSource::operator= (const MouseInputSource& other) noexcept | |||
| { | |||
| pimpl = new MouseInputSourceInternal (*this, index, isMouseDevice); | |||
| pimpl = other.pimpl; | |||
| return *this; | |||
| } | |||
| MouseInputSource::~MouseInputSource() {} | |||
| bool MouseInputSource::isMouse() const { return pimpl->isMouseDevice; } | |||
| bool MouseInputSource::isTouch() const { return ! isMouse(); } | |||
| bool MouseInputSource::canHover() const { return isMouse(); } | |||
| @@ -546,7 +548,8 @@ Time MouseInputSource::getLastMouseDownTime() const noexcept { return | |||
| Point<int> MouseInputSource::getLastMouseDownPosition() const noexcept { return pimpl->getLastMouseDownPosition(); } | |||
| bool MouseInputSource::hasMouseMovedSignificantlySincePressed() const noexcept { return pimpl->hasMouseMovedSignificantlySincePressed(); } | |||
| bool MouseInputSource::canDoUnboundedMovement() const noexcept { return isMouse(); } | |||
| void MouseInputSource::enableUnboundedMouseMovement (bool isEnabled, bool keepCursorVisibleUntilOffscreen) { pimpl->enableUnboundedMouseMovement (isEnabled, keepCursorVisibleUntilOffscreen); } | |||
| void MouseInputSource::enableUnboundedMouseMovement (bool isEnabled, bool keepCursorVisibleUntilOffscreen) const | |||
| { pimpl->enableUnboundedMouseMovement (isEnabled, keepCursorVisibleUntilOffscreen); } | |||
| bool MouseInputSource::hasMouseCursor() const noexcept { return isMouse(); } | |||
| void MouseInputSource::showMouseCursor (const MouseCursor& cursor) { pimpl->showMouseCursor (cursor, false); } | |||
| void MouseInputSource::hideCursor() { pimpl->hideCursor(); } | |||
| @@ -571,3 +574,110 @@ void MouseInputSource::handleMagnifyGesture (ComponentPeer& peer, Point<int> pos | |||
| { | |||
| pimpl->handleMagnifyGesture (peer, positionWithinPeer, Time (time), scaleFactor); | |||
| } | |||
| //============================================================================== | |||
| struct MouseInputSource::SourceList : public Timer | |||
| { | |||
| SourceList() | |||
| { | |||
| addSource(); | |||
| } | |||
| bool addSource(); | |||
| void addSource (int index, bool isMouse) | |||
| { | |||
| MouseInputSourceInternal* s = new MouseInputSourceInternal (index, isMouse); | |||
| sources.add (s); | |||
| sourceArray.add (MouseInputSource (s)); | |||
| } | |||
| MouseInputSource* getMouseSource (int index) const noexcept | |||
| { | |||
| return isPositiveAndBelow (index, sourceArray.size()) ? &sourceArray.getReference (index) | |||
| : nullptr; | |||
| } | |||
| MouseInputSource* getOrCreateMouseInputSource (int touchIndex) | |||
| { | |||
| jassert (touchIndex >= 0 && touchIndex < 100); // sanity-check on number of fingers | |||
| for (;;) | |||
| { | |||
| if (MouseInputSource* mouse = getMouseSource (touchIndex)) | |||
| return mouse; | |||
| if (! addSource()) | |||
| { | |||
| jassertfalse; // not enough mouse sources! | |||
| return nullptr; | |||
| } | |||
| } | |||
| } | |||
| int getNumDraggingMouseSources() const noexcept | |||
| { | |||
| int num = 0; | |||
| for (int i = 0; i < sources.size(); ++i) | |||
| if (sources.getUnchecked(i)->isDragging()) | |||
| ++num; | |||
| return num; | |||
| } | |||
| MouseInputSource* getDraggingMouseSource (int index) const noexcept | |||
| { | |||
| int num = 0; | |||
| for (int i = 0; i < sources.size(); ++i) | |||
| { | |||
| MouseInputSource* const mi = &(sourceArray.getReference(i)); | |||
| if (mi->isDragging()) | |||
| { | |||
| if (index == num) | |||
| return mi; | |||
| ++num; | |||
| } | |||
| } | |||
| return nullptr; | |||
| } | |||
| void beginDragAutoRepeat (const int interval) | |||
| { | |||
| if (interval > 0) | |||
| { | |||
| if (getTimerInterval() != interval) | |||
| startTimer (interval); | |||
| } | |||
| else | |||
| { | |||
| stopTimer(); | |||
| } | |||
| } | |||
| void timerCallback() override | |||
| { | |||
| int numMiceDown = 0; | |||
| for (int i = 0; i < sources.size(); ++i) | |||
| { | |||
| MouseInputSourceInternal* const mi = sources.getUnchecked(i); | |||
| if (mi->isDragging()) | |||
| { | |||
| mi->triggerFakeMove(); | |||
| ++numMiceDown; | |||
| } | |||
| } | |||
| if (numMiceDown == 0) | |||
| stopTimer(); | |||
| } | |||
| OwnedArray<MouseInputSourceInternal> sources; | |||
| Array<MouseInputSource> sourceArray; | |||
| }; | |||
| @@ -50,14 +50,13 @@ class JUCE_API MouseInputSource | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| /** Creates a MouseInputSource. | |||
| You should never actually create a MouseInputSource in your own code - the | |||
| library takes care of managing these objects. | |||
| */ | |||
| MouseInputSource (int index, bool isMouseDevice); | |||
| MouseInputSource (const MouseInputSource&) noexcept; | |||
| MouseInputSource& operator= (const MouseInputSource&) noexcept; | |||
| ~MouseInputSource() noexcept; | |||
| /** Destructor. */ | |||
| ~MouseInputSource(); | |||
| //============================================================================== | |||
| bool operator== (const MouseInputSource& other) const noexcept { return pimpl == other.pimpl; } | |||
| bool operator!= (const MouseInputSource& other) const noexcept { return pimpl != other.pimpl; } | |||
| //============================================================================== | |||
| /** Returns true if this object represents a normal desk-based mouse device. */ | |||
| @@ -157,7 +156,7 @@ public: | |||
| hidden; if true, it will only be hidden when it | |||
| is moved beyond the edge of the screen | |||
| */ | |||
| void enableUnboundedMouseMovement (bool isEnabled, bool keepCursorVisibleUntilOffscreen = false); | |||
| void enableUnboundedMouseMovement (bool isEnabled, bool keepCursorVisibleUntilOffscreen = false) const; | |||
| /** Attempts to set this mouse pointer's screen position. */ | |||
| void setScreenPosition (Point<int> newPosition); | |||
| @@ -165,9 +164,13 @@ public: | |||
| private: | |||
| //============================================================================== | |||
| friend class ComponentPeer; | |||
| friend class Desktop; | |||
| friend class MouseInputSourceInternal; | |||
| ScopedPointer<MouseInputSourceInternal> pimpl; | |||
| MouseInputSourceInternal* pimpl; | |||
| struct SourceList; | |||
| explicit MouseInputSource (MouseInputSourceInternal*) noexcept; | |||
| void handleEvent (ComponentPeer&, Point<int>, int64 time, const ModifierKeys); | |||
| void handleWheel (ComponentPeer&, Point<int>, int64 time, const MouseWheelDetails&); | |||
| void handleMagnifyGesture (ComponentPeer&, Point<int>, int64 time, float scaleFactor); | |||
| @@ -175,7 +178,7 @@ private: | |||
| static Point<int> getCurrentRawMousePosition(); | |||
| static void setRawMousePosition (Point<int>); | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MouseInputSource) | |||
| JUCE_LEAK_DETECTOR (MouseInputSource) | |||
| }; | |||
| @@ -588,9 +588,9 @@ Desktop::DisplayOrientation Desktop::getCurrentOrientation() const | |||
| return upright; | |||
| } | |||
| bool Desktop::addMouseInputSource() | |||
| bool MouseInputSource::SourceList::addSource() | |||
| { | |||
| mouseSources.add (new MouseInputSource (mouseSources.size(), false)); | |||
| addSource (sources.size(), false); | |||
| return true; | |||
| } | |||
| @@ -279,9 +279,9 @@ String SystemClipboard::getTextFromClipboard() | |||
| } | |||
| //============================================================================== | |||
| bool Desktop::addMouseInputSource() | |||
| bool MouseInputSource::SourceList::addSource() | |||
| { | |||
| mouseSources.add (new MouseInputSource (mouseSources.size(), false)); | |||
| addSource (sources.size(), false); | |||
| return true; | |||
| } | |||
| @@ -3095,11 +3095,11 @@ void Desktop::Displays::findDisplays (float masterScale) | |||
| } | |||
| //============================================================================== | |||
| bool Desktop::addMouseInputSource() | |||
| bool MouseInputSource::SourceList::addSource() | |||
| { | |||
| if (mouseSources.size() == 0) | |||
| if (sources.size() == 0) | |||
| { | |||
| mouseSources.add (new MouseInputSource (0, true)); | |||
| addSource (0, true); | |||
| return true; | |||
| } | |||
| @@ -915,7 +915,7 @@ public: | |||
| static void showArrowCursorIfNeeded() | |||
| { | |||
| Desktop& desktop = Desktop::getInstance(); | |||
| MouseInputSource& mouse = desktop.getMainMouseSource(); | |||
| MouseInputSource mouse = desktop.getMainMouseSource(); | |||
| if (mouse.getComponentUnderMouse() == nullptr | |||
| && desktop.findComponentAt (mouse.getScreenPosition()) == nullptr) | |||
| @@ -1844,11 +1844,11 @@ void ModifierKeys::updateCurrentModifiers() noexcept | |||
| //============================================================================== | |||
| bool Desktop::addMouseInputSource() | |||
| bool MouseInputSource::SourceList::addSource() | |||
| { | |||
| if (mouseSources.size() == 0) | |||
| if (sources.size() == 0) | |||
| { | |||
| mouseSources.add (new MouseInputSource (0, true)); | |||
| addSource (0, true); | |||
| return true; | |||
| } | |||
| @@ -3040,13 +3040,13 @@ int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconTy | |||
| } | |||
| //============================================================================== | |||
| bool Desktop::addMouseInputSource() | |||
| bool MouseInputSource::SourceList::addSource() | |||
| { | |||
| const int numSources = mouseSources.size(); | |||
| const int numSources = sources.size(); | |||
| if (numSources == 0 || canUseMultiTouch()) | |||
| { | |||
| mouseSources.add (new MouseInputSource (numSources, numSources == 0)); | |||
| addSource (numSources, numSources == 0); | |||
| return true; | |||
| } | |||
| @@ -1033,10 +1033,10 @@ public: | |||
| { | |||
| mouseWasHidden = false; | |||
| const OwnedArray<MouseInputSource>& mouseSources = Desktop::getInstance().getMouseSources(); | |||
| const Array<MouseInputSource>& mouseSources = Desktop::getInstance().getMouseSources(); | |||
| for (MouseInputSource** i = mouseSources.begin(), ** const e = mouseSources.end(); i != e; ++i) | |||
| (*i)->enableUnboundedMouseMovement (false); | |||
| for (MouseInputSource* mi = mouseSources.begin(), * const e = mouseSources.end(); mi != e; ++mi) | |||
| mi->enableUnboundedMouseMovement (false); | |||
| const double pos = sliderBeingDragged == 2 ? getMaxValue() | |||
| : (sliderBeingDragged == 1 ? getMinValue() | |||
| @@ -367,14 +367,12 @@ private: | |||
| static bool isMouseDraggingInChildCompOf (Component* const comp) | |||
| { | |||
| const OwnedArray<MouseInputSource>& mouseSources = Desktop::getInstance().getMouseSources(); | |||
| const Array<MouseInputSource>& mouseSources = Desktop::getInstance().getMouseSources(); | |||
| for (MouseInputSource** i = mouseSources.begin(), ** const e = mouseSources.end(); i != e; ++i) | |||
| for (MouseInputSource* mi = mouseSources.begin(), * const e = mouseSources.end(); mi != e; ++mi) | |||
| { | |||
| MouseInputSource& source = **i; | |||
| if (source.isDragging()) | |||
| if (Component* const underMouse = source.getComponentUnderMouse()) | |||
| if (mi->isDragging()) | |||
| if (Component* const underMouse = mi->getComponentUnderMouse()) | |||
| if (comp == underMouse || comp->isParentOf (underMouse)) | |||
| return true; | |||
| } | |||
| @@ -83,22 +83,22 @@ void ComponentPeer::updateBounds() | |||
| void ComponentPeer::handleMouseEvent (const int touchIndex, const Point<int> positionWithinPeer, | |||
| const ModifierKeys newMods, const int64 time) | |||
| { | |||
| if (MouseInputSource* mouse = Desktop::getInstance().getOrCreateMouseInputSource (touchIndex)) | |||
| mouse->handleEvent (*this, positionWithinPeer, time, newMods); | |||
| if (MouseInputSource* mouse = Desktop::getInstance().mouseSources->getOrCreateMouseInputSource (touchIndex)) | |||
| MouseInputSource (*mouse).handleEvent (*this, positionWithinPeer, time, newMods); | |||
| } | |||
| void ComponentPeer::handleMouseWheel (const int touchIndex, const Point<int> positionWithinPeer, | |||
| const int64 time, const MouseWheelDetails& wheel) | |||
| { | |||
| if (MouseInputSource* mouse = Desktop::getInstance().getOrCreateMouseInputSource (touchIndex)) | |||
| mouse->handleWheel (*this, positionWithinPeer, time, wheel); | |||
| if (MouseInputSource* mouse = Desktop::getInstance().mouseSources->getOrCreateMouseInputSource (touchIndex)) | |||
| MouseInputSource (*mouse).handleWheel (*this, positionWithinPeer, time, wheel); | |||
| } | |||
| void ComponentPeer::handleMagnifyGesture (const int touchIndex, const Point<int> positionWithinPeer, | |||
| const int64 time, const float scaleFactor) | |||
| { | |||
| if (MouseInputSource* mouse = Desktop::getInstance().getOrCreateMouseInputSource (touchIndex)) | |||
| mouse->handleMagnifyGesture (*this, positionWithinPeer, time, scaleFactor); | |||
| if (MouseInputSource* mouse = Desktop::getInstance().mouseSources->getOrCreateMouseInputSource (touchIndex)) | |||
| MouseInputSource (*mouse).handleMagnifyGesture (*this, positionWithinPeer, time, scaleFactor); | |||
| } | |||
| //============================================================================== | |||
| @@ -94,24 +94,23 @@ public: | |||
| const Time now (Time::getCurrentTime()); | |||
| MouseInputSource mouseSource = Desktop::getInstance().getMainMouseSource(); | |||
| if (isLeft || isRight) // Only mouse up is sent by the OS, so simulate a down/up | |||
| { | |||
| owner.mouseDown (MouseEvent (Desktop::getInstance().getMainMouseSource(), | |||
| Point<int>(), | |||
| owner.mouseDown (MouseEvent (mouseSource, Point<int>(), | |||
| eventMods.withFlags (isLeft ? ModifierKeys::leftButtonModifier | |||
| : ModifierKeys::rightButtonModifier), | |||
| &owner, &owner, now, | |||
| Point<int>(), now, 1, false)); | |||
| owner.mouseUp (MouseEvent (Desktop::getInstance().getMainMouseSource(), | |||
| Point<int>(), eventMods.withoutMouseButtons(), | |||
| owner.mouseUp (MouseEvent (mouseSource, Point<int>(), eventMods.withoutMouseButtons(), | |||
| &owner, &owner, now, | |||
| Point<int>(), now, 1, false)); | |||
| } | |||
| else if (type == NSMouseMoved) | |||
| { | |||
| owner.mouseMove (MouseEvent (Desktop::getInstance().getMainMouseSource(), | |||
| Point<int>(), eventMods, | |||
| owner.mouseMove (MouseEvent (mouseSource, Point<int>(), eventMods, | |||
| &owner, &owner, now, | |||
| Point<int>(), now, 1, false)); | |||
| } | |||