@@ -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)); | |||
} | |||