From be1d5253ee2cc7c67ca41228c84f2c5f2a7e94c8 Mon Sep 17 00:00:00 2001 From: jules Date: Tue, 3 Sep 2013 10:44:55 +0100 Subject: [PATCH] Moved some mouse code out of Desktop class. Made the MouseInputSource class pass-by-value. --- .../gui/juce_MidiKeyboardComponent.cpp | 10 +- .../zip/juce_GZIPDecompressorInputStream.cpp | 12 +- .../components/juce_Component.cpp | 44 +++--- .../components/juce_Component.h | 16 +- .../components/juce_Desktop.cpp | 119 ++------------- .../juce_gui_basics/components/juce_Desktop.h | 30 ++-- modules/juce_gui_basics/juce_gui_basics.cpp | 2 +- modules/juce_gui_basics/juce_gui_basics.h | 2 +- .../juce_gui_basics/menus/juce_PopupMenu.cpp | 8 +- .../juce_gui_basics/mouse/juce_MouseEvent.cpp | 2 +- .../juce_gui_basics/mouse/juce_MouseEvent.h | 4 +- .../mouse/juce_MouseInputSource.cpp | 142 ++++++++++++++++-- .../mouse/juce_MouseInputSource.h | 23 +-- .../native/juce_android_Windowing.cpp | 4 +- .../native/juce_ios_Windowing.mm | 4 +- .../native/juce_linux_Windowing.cpp | 6 +- .../native/juce_mac_NSViewComponentPeer.mm | 8 +- .../native/juce_win32_Windowing.cpp | 6 +- .../juce_gui_basics/widgets/juce_Slider.cpp | 6 +- .../juce_gui_basics/widgets/juce_TreeView.cpp | 10 +- .../windows/juce_ComponentPeer.cpp | 12 +- .../native/juce_mac_SystemTrayIcon.cpp | 11 +- 22 files changed, 245 insertions(+), 236 deletions(-) diff --git a/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.cpp b/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.cpp index 8d5c9a919f..8a6affc682 100644 --- a/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.cpp +++ b/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.cpp @@ -818,14 +818,10 @@ void MidiKeyboardComponent::timerCallback() if (shouldCheckMousePos) { - const OwnedArray& mouseSources = Desktop::getInstance().getMouseSources(); + const Array& 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()); } } diff --git a/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp b/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp index d67c6a557d..4a72305be6 100644 --- a/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp +++ b/modules/juce_core/zip/juce_GZIPDecompressorInputStream.cpp @@ -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)) diff --git a/modules/juce_gui_basics/components/juce_Component.cpp b/modules/juce_gui_basics/components/juce_Component.cpp index 0ec31c7252..534640f803 100644 --- a/modules/juce_gui_basics/components/juce_Component.cpp +++ b/modules/juce_gui_basics/components/juce_Component.cpp @@ -2310,7 +2310,7 @@ void Component::removeMouseListener (MouseListener* const listenerToRemove) } //============================================================================== -void Component::internalMouseEnter (MouseInputSource& source, Point relativePos, Time time) +void Component::internalMouseEnter (MouseInputSource source, Point relativePos, Time time) { if (isCurrentlyBlockedByAnotherModalComponent()) { @@ -2336,7 +2336,7 @@ void Component::internalMouseEnter (MouseInputSource& source, Point relativ MouseListenerList::sendMouseEvent (*this, checker, &MouseListener::mouseEnter, me); } -void Component::internalMouseExit (MouseInputSource& source, Point relativePos, Time time) +void Component::internalMouseExit (MouseInputSource source, Point relativePos, Time time) { if (flags.repaintOnMouseActivityFlag) repaint(); @@ -2356,7 +2356,7 @@ void Component::internalMouseExit (MouseInputSource& source, Point relative MouseListenerList::sendMouseEvent (*this, checker, &MouseListener::mouseExit, me); } -void Component::internalMouseDown (MouseInputSource& source, Point relativePos, Time time) +void Component::internalMouseDown (MouseInputSource source, Point relativePos, Time time) { Desktop& desktop = Desktop::getInstance(); BailOutChecker checker (this); @@ -2420,7 +2420,7 @@ void Component::internalMouseDown (MouseInputSource& source, Point relative MouseListenerList::sendMouseEvent (*this, checker, &MouseListener::mouseDown, me); } -void Component::internalMouseUp (MouseInputSource& source, Point relativePos, +void Component::internalMouseUp (MouseInputSource source, Point relativePos, Time time, const ModifierKeys oldModifiers) { if (flags.mouseDownWasBlocked && isCurrentlyBlockedByAnotherModalComponent()) @@ -2463,7 +2463,7 @@ void Component::internalMouseUp (MouseInputSource& source, Point relativePo } } -void Component::internalMouseDrag (MouseInputSource& source, Point relativePos, Time time) +void Component::internalMouseDrag (MouseInputSource source, Point relativePos, Time time) { if (! isCurrentlyBlockedByAnotherModalComponent()) { @@ -2486,7 +2486,7 @@ void Component::internalMouseDrag (MouseInputSource& source, Point relative } } -void Component::internalMouseMove (MouseInputSource& source, Point relativePos, Time time) +void Component::internalMouseMove (MouseInputSource source, Point relativePos, Time time) { Desktop& desktop = Desktop::getInstance(); @@ -2512,7 +2512,7 @@ void Component::internalMouseMove (MouseInputSource& source, Point relative } } -void Component::internalMouseWheel (MouseInputSource& source, Point relativePos, +void Component::internalMouseWheel (MouseInputSource source, Point relativePos, Time time, const MouseWheelDetails& wheel) { Desktop& desktop = Desktop::getInstance(); @@ -2540,7 +2540,7 @@ void Component::internalMouseWheel (MouseInputSource& source, Point relativ } } -void Component::internalMagnifyGesture (MouseInputSource& source, Point relativePos, +void Component::internalMagnifyGesture (MouseInputSource source, Point relativePos, Time time, float amount) { if (! isCurrentlyBlockedByAnotherModalComponent()) @@ -2554,7 +2554,7 @@ void Component::internalMagnifyGesture (MouseInputSource& source, Point 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& mouseSources = Desktop::getInstance().getMouseSources(); + const Array& 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& mouseSources = Desktop::getInstance().getMouseSources(); + const Array& 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& mouseSources = Desktop::getInstance().getMouseSources(); + const Array& 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; diff --git a/modules/juce_gui_basics/components/juce_Component.h b/modules/juce_gui_basics/components/juce_Component.h index 9a699a0d84..9de449dfc9 100644 --- a/modules/juce_gui_basics/components/juce_Component.h +++ b/modules/juce_gui_basics/components/juce_Component.h @@ -2280,14 +2280,14 @@ private: uint8 componentTransparency; //============================================================================== - void internalMouseEnter (MouseInputSource&, Point, Time); - void internalMouseExit (MouseInputSource&, Point, Time); - void internalMouseDown (MouseInputSource&, Point, Time); - void internalMouseUp (MouseInputSource&, Point, Time, const ModifierKeys oldModifiers); - void internalMouseDrag (MouseInputSource&, Point, Time); - void internalMouseMove (MouseInputSource&, Point, Time); - void internalMouseWheel (MouseInputSource&, Point, Time, const MouseWheelDetails&); - void internalMagnifyGesture (MouseInputSource&, Point, Time, float); + void internalMouseEnter (MouseInputSource, Point, Time); + void internalMouseExit (MouseInputSource, Point, Time); + void internalMouseDown (MouseInputSource, Point, Time); + void internalMouseUp (MouseInputSource, Point, Time, const ModifierKeys oldModifiers); + void internalMouseDrag (MouseInputSource, Point, Time); + void internalMouseMove (MouseInputSource, Point, Time); + void internalMouseWheel (MouseInputSource, Point, Time, const MouseWheelDetails&); + void internalMagnifyGesture (MouseInputSource, Point, Time, float); void internalBroughtToFront(); void internalFocusGain (const FocusChangeType, const WeakReference&); void internalFocusGain (const FocusChangeType); diff --git a/modules/juce_gui_basics/components/juce_Desktop.cpp b/modules/juce_gui_basics/components/juce_Desktop.cpp index 50ccfc91cf..39a4107c31 100644 --- a/modules/juce_gui_basics/components/juce_Desktop.cpp +++ b/modules/juce_gui_basics/components/juce_Desktop.cpp @@ -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& 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& 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() { diff --git a/modules/juce_gui_basics/components/juce_Desktop.h b/modules/juce_gui_basics/components/juce_Desktop.h index dc0a238b4a..5900004a13 100644 --- a/modules/juce_gui_basics/components/juce_Desktop.h +++ b/modules/juce_gui_basics/components/juce_Desktop.h @@ -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& 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& 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 mouseSources; - bool addMouseInputSource(); + ScopedPointer mouseSources; ListenerList mouseListeners; ListenerList focusListeners; @@ -418,8 +421,6 @@ private: void incrementMouseClickCounter() noexcept; void incrementMouseWheelCounter() noexcept; - ScopedPointer dragRepeater; - ScopedPointer defaultLookAndFeel; WeakReference currentLookAndFeel; @@ -434,7 +435,6 @@ private: void timerCallback() override; void resetTimer(); ListenerList& getMouseListeners(); - MouseInputSource* getOrCreateMouseInputSource (int touchIndex); void addDesktopComponent (Component*); void removeDesktopComponent (Component*); diff --git a/modules/juce_gui_basics/juce_gui_basics.cpp b/modules/juce_gui_basics/juce_gui_basics.cpp index f35a5e8b7e..c168c679bc 100644 --- a/modules/juce_gui_basics/juce_gui_basics.cpp +++ b/modules/juce_gui_basics/juce_gui_basics.cpp @@ -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" diff --git a/modules/juce_gui_basics/juce_gui_basics.h b/modules/juce_gui_basics/juce_gui_basics.h index 82787e9e93..376611f88a 100644 --- a/modules/juce_gui_basics/juce_gui_basics.h +++ b/modules/juce_gui_basics/juce_gui_basics.h @@ -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" diff --git a/modules/juce_gui_basics/menus/juce_PopupMenu.cpp b/modules/juce_gui_basics/menus/juce_PopupMenu.cpp index b26c8ee0ad..1269680054 100644 --- a/modules/juce_gui_basics/menus/juce_PopupMenu.cpp +++ b/modules/juce_gui_basics/menus/juce_PopupMenu.cpp @@ -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 lastMousePos; diff --git a/modules/juce_gui_basics/mouse/juce_MouseEvent.cpp b/modules/juce_gui_basics/mouse/juce_MouseEvent.cpp index 03919e4650..db1ad12951 100644 --- a/modules/juce_gui_basics/mouse/juce_MouseEvent.cpp +++ b/modules/juce_gui_basics/mouse/juce_MouseEvent.cpp @@ -22,7 +22,7 @@ ============================================================================== */ -MouseEvent::MouseEvent (MouseInputSource& inputSource, +MouseEvent::MouseEvent (MouseInputSource inputSource, Point position, ModifierKeys modKeys, Component* const eventComp, diff --git a/modules/juce_gui_basics/mouse/juce_MouseEvent.h b/modules/juce_gui_basics/mouse/juce_MouseEvent.h index 6256a66ed2..87328b1c18 100644 --- a/modules/juce_gui_basics/mouse/juce_MouseEvent.h +++ b/modules/juce_gui_basics/mouse/juce_MouseEvent.h @@ -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 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. diff --git a/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp b/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp index cb16e2d612..07c5dfa6f8 100644 --- a/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp +++ b/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp @@ -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 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 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 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 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 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 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 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 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 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 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 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 sources; + Array sourceArray; +}; diff --git a/modules/juce_gui_basics/mouse/juce_MouseInputSource.h b/modules/juce_gui_basics/mouse/juce_MouseInputSource.h index e443342862..8185098990 100644 --- a/modules/juce_gui_basics/mouse/juce_MouseInputSource.h +++ b/modules/juce_gui_basics/mouse/juce_MouseInputSource.h @@ -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 newPosition); @@ -165,9 +164,13 @@ public: private: //============================================================================== friend class ComponentPeer; + friend class Desktop; friend class MouseInputSourceInternal; - ScopedPointer pimpl; + MouseInputSourceInternal* pimpl; + + struct SourceList; + explicit MouseInputSource (MouseInputSourceInternal*) noexcept; void handleEvent (ComponentPeer&, Point, int64 time, const ModifierKeys); void handleWheel (ComponentPeer&, Point, int64 time, const MouseWheelDetails&); void handleMagnifyGesture (ComponentPeer&, Point, int64 time, float scaleFactor); @@ -175,7 +178,7 @@ private: static Point getCurrentRawMousePosition(); static void setRawMousePosition (Point); - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MouseInputSource) + JUCE_LEAK_DETECTOR (MouseInputSource) }; diff --git a/modules/juce_gui_basics/native/juce_android_Windowing.cpp b/modules/juce_gui_basics/native/juce_android_Windowing.cpp index ca87fad848..3e79136a5b 100644 --- a/modules/juce_gui_basics/native/juce_android_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_android_Windowing.cpp @@ -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; } diff --git a/modules/juce_gui_basics/native/juce_ios_Windowing.mm b/modules/juce_gui_basics/native/juce_ios_Windowing.mm index c78f6b3bc3..4a4afb9b82 100644 --- a/modules/juce_gui_basics/native/juce_ios_Windowing.mm +++ b/modules/juce_gui_basics/native/juce_ios_Windowing.mm @@ -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; } diff --git a/modules/juce_gui_basics/native/juce_linux_Windowing.cpp b/modules/juce_gui_basics/native/juce_linux_Windowing.cpp index d951daff79..b0357306d7 100644 --- a/modules/juce_gui_basics/native/juce_linux_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_linux_Windowing.cpp @@ -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; } diff --git a/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm b/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm index f78830d731..c531b34129 100644 --- a/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm +++ b/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm @@ -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; } diff --git a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp index 2e507f7e8a..92cbd9c144 100644 --- a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp @@ -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; } diff --git a/modules/juce_gui_basics/widgets/juce_Slider.cpp b/modules/juce_gui_basics/widgets/juce_Slider.cpp index ae8d5d6db7..3327e558e5 100644 --- a/modules/juce_gui_basics/widgets/juce_Slider.cpp +++ b/modules/juce_gui_basics/widgets/juce_Slider.cpp @@ -1033,10 +1033,10 @@ public: { mouseWasHidden = false; - const OwnedArray& mouseSources = Desktop::getInstance().getMouseSources(); + const Array& 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() diff --git a/modules/juce_gui_basics/widgets/juce_TreeView.cpp b/modules/juce_gui_basics/widgets/juce_TreeView.cpp index 8c66cfd86a..c7672e0cb1 100644 --- a/modules/juce_gui_basics/widgets/juce_TreeView.cpp +++ b/modules/juce_gui_basics/widgets/juce_TreeView.cpp @@ -367,14 +367,12 @@ private: static bool isMouseDraggingInChildCompOf (Component* const comp) { - const OwnedArray& mouseSources = Desktop::getInstance().getMouseSources(); + const Array& 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; } diff --git a/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp b/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp index b79162ad88..8b59a7ca00 100644 --- a/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp +++ b/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp @@ -83,22 +83,22 @@ void ComponentPeer::updateBounds() void ComponentPeer::handleMouseEvent (const int touchIndex, const Point 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 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 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); } //============================================================================== diff --git a/modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp b/modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp index 84f4a8cca6..b6ea3c1d39 100644 --- a/modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp +++ b/modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp @@ -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(), + owner.mouseDown (MouseEvent (mouseSource, Point(), eventMods.withFlags (isLeft ? ModifierKeys::leftButtonModifier : ModifierKeys::rightButtonModifier), &owner, &owner, now, Point(), now, 1, false)); - owner.mouseUp (MouseEvent (Desktop::getInstance().getMainMouseSource(), - Point(), eventMods.withoutMouseButtons(), + owner.mouseUp (MouseEvent (mouseSource, Point(), eventMods.withoutMouseButtons(), &owner, &owner, now, Point(), now, 1, false)); } else if (type == NSMouseMoved) { - owner.mouseMove (MouseEvent (Desktop::getInstance().getMainMouseSource(), - Point(), eventMods, + owner.mouseMove (MouseEvent (mouseSource, Point(), eventMods, &owner, &owner, now, Point(), now, 1, false)); }