mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Multiple fixes for touch and pen input on Windows
This commit is contained in:
parent
2e08db47ff
commit
b7b8d5be57
21 changed files with 569 additions and 196 deletions
|
|
@ -2402,6 +2402,8 @@ void Component::internalMouseEnter (MouseInputSource source, Point<float> relati
|
|||
BailOutChecker checker (this);
|
||||
|
||||
const MouseEvent me (source, relativePos, source.getCurrentModifiers(), MouseInputSource::invalidPressure,
|
||||
MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation,
|
||||
MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY,
|
||||
this, this, time, relativePos, time, 0, false);
|
||||
mouseEnter (me);
|
||||
|
||||
|
|
@ -2428,6 +2430,8 @@ void Component::internalMouseExit (MouseInputSource source, Point<float> relativ
|
|||
BailOutChecker checker (this);
|
||||
|
||||
const MouseEvent me (source, relativePos, source.getCurrentModifiers(), MouseInputSource::invalidPressure,
|
||||
MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation,
|
||||
MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY,
|
||||
this, this, time, relativePos, time, 0, false);
|
||||
|
||||
mouseExit (me);
|
||||
|
|
@ -2440,7 +2444,8 @@ void Component::internalMouseExit (MouseInputSource source, Point<float> relativ
|
|||
MouseListenerList::sendMouseEvent (*this, checker, &MouseListener::mouseExit, me);
|
||||
}
|
||||
|
||||
void Component::internalMouseDown (MouseInputSource source, Point<float> relativePos, Time time, float pressure)
|
||||
void Component::internalMouseDown (MouseInputSource source, Point<float> relativePos, Time time,
|
||||
float pressure, float orientation, float rotation, float tiltX, float tiltY)
|
||||
{
|
||||
Desktop& desktop = Desktop::getInstance();
|
||||
BailOutChecker checker (this);
|
||||
|
|
@ -2458,9 +2463,9 @@ void Component::internalMouseDown (MouseInputSource source, Point<float> relativ
|
|||
if (isCurrentlyBlockedByAnotherModalComponent())
|
||||
{
|
||||
// allow blocked mouse-events to go to global listeners..
|
||||
const MouseEvent me (source, relativePos, source.getCurrentModifiers(),
|
||||
pressure, this, this, time, relativePos, time,
|
||||
source.getNumberOfMultipleClicks(), false);
|
||||
const MouseEvent me (source, relativePos, source.getCurrentModifiers(), pressure,
|
||||
orientation, rotation, tiltX, tiltY, this, this, time, relativePos,
|
||||
time, source.getNumberOfMultipleClicks(), false);
|
||||
|
||||
desktop.getMouseListeners().callChecked (checker, &MouseListener::mouseDown, me);
|
||||
return;
|
||||
|
|
@ -2491,9 +2496,9 @@ void Component::internalMouseDown (MouseInputSource source, Point<float> relativ
|
|||
if (flags.repaintOnMouseActivityFlag)
|
||||
repaint();
|
||||
|
||||
const MouseEvent me (source, relativePos, source.getCurrentModifiers(),
|
||||
pressure, this, this, time, relativePos, time,
|
||||
source.getNumberOfMultipleClicks(), false);
|
||||
const MouseEvent me (source, relativePos, source.getCurrentModifiers(), pressure,
|
||||
orientation, rotation, tiltX, tiltY, this, this, time, relativePos,
|
||||
time, source.getNumberOfMultipleClicks(), false);
|
||||
mouseDown (me);
|
||||
|
||||
if (checker.shouldBailOut())
|
||||
|
|
@ -2504,8 +2509,8 @@ void Component::internalMouseDown (MouseInputSource source, Point<float> relativ
|
|||
MouseListenerList::sendMouseEvent (*this, checker, &MouseListener::mouseDown, me);
|
||||
}
|
||||
|
||||
void Component::internalMouseUp (MouseInputSource source, Point<float> relativePos,
|
||||
Time time, const ModifierKeys oldModifiers, float pressure)
|
||||
void Component::internalMouseUp (MouseInputSource source, Point<float> relativePos, Time time,
|
||||
const ModifierKeys oldModifiers, float pressure, float orientation, float rotation, float tiltX, float tiltY)
|
||||
{
|
||||
if (flags.mouseDownWasBlocked && isCurrentlyBlockedByAnotherModalComponent())
|
||||
return;
|
||||
|
|
@ -2515,8 +2520,8 @@ void Component::internalMouseUp (MouseInputSource source, Point<float> relativeP
|
|||
if (flags.repaintOnMouseActivityFlag)
|
||||
repaint();
|
||||
|
||||
const MouseEvent me (source, relativePos,
|
||||
oldModifiers, pressure, this, this, time,
|
||||
const MouseEvent me (source, relativePos, oldModifiers, pressure, orientation,
|
||||
rotation, tiltX, tiltY, this, this, time,
|
||||
getLocalPoint (nullptr, source.getLastMouseDownPosition()),
|
||||
source.getLastMouseDownTime(),
|
||||
source.getNumberOfMultipleClicks(),
|
||||
|
|
@ -2547,14 +2552,15 @@ void Component::internalMouseUp (MouseInputSource source, Point<float> relativeP
|
|||
}
|
||||
}
|
||||
|
||||
void Component::internalMouseDrag (MouseInputSource source, Point<float> relativePos, Time time, float pressure)
|
||||
void Component::internalMouseDrag (MouseInputSource source, Point<float> relativePos, Time time,
|
||||
float pressure, float orientation, float rotation, float tiltX, float tiltY)
|
||||
{
|
||||
if (! isCurrentlyBlockedByAnotherModalComponent())
|
||||
{
|
||||
BailOutChecker checker (this);
|
||||
|
||||
const MouseEvent me (source, relativePos, source.getCurrentModifiers(),
|
||||
pressure, this, this, time,
|
||||
pressure, orientation, rotation, tiltX, tiltY, this, this, time,
|
||||
getLocalPoint (nullptr, source.getLastMouseDownPosition()),
|
||||
source.getLastMouseDownTime(),
|
||||
source.getNumberOfMultipleClicks(),
|
||||
|
|
@ -2584,6 +2590,8 @@ void Component::internalMouseMove (MouseInputSource source, Point<float> relativ
|
|||
BailOutChecker checker (this);
|
||||
|
||||
const MouseEvent me (source, relativePos, source.getCurrentModifiers(), MouseInputSource::invalidPressure,
|
||||
MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation,
|
||||
MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY,
|
||||
this, this, time, relativePos, time, 0, false);
|
||||
mouseMove (me);
|
||||
|
||||
|
|
@ -2603,6 +2611,8 @@ void Component::internalMouseWheel (MouseInputSource source, Point<float> relati
|
|||
BailOutChecker checker (this);
|
||||
|
||||
const MouseEvent me (source, relativePos, source.getCurrentModifiers(), MouseInputSource::invalidPressure,
|
||||
MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation,
|
||||
MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY,
|
||||
this, this, time, relativePos, time, 0, false);
|
||||
|
||||
if (isCurrentlyBlockedByAnotherModalComponent())
|
||||
|
|
@ -2630,6 +2640,8 @@ void Component::internalMagnifyGesture (MouseInputSource source, Point<float> re
|
|||
if (! isCurrentlyBlockedByAnotherModalComponent())
|
||||
{
|
||||
const MouseEvent me (source, relativePos, source.getCurrentModifiers(), MouseInputSource::invalidPressure,
|
||||
MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation,
|
||||
MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY,
|
||||
this, this, time, relativePos, time, 0, false);
|
||||
|
||||
mouseMagnify (me, amount);
|
||||
|
|
@ -2967,15 +2979,13 @@ void Component::sendEnablementChangeMessage()
|
|||
//==============================================================================
|
||||
bool Component::isMouseOver (const bool includeChildren) const
|
||||
{
|
||||
const Array<MouseInputSource>& mouseSources = Desktop::getInstance().getMouseSources();
|
||||
|
||||
for (MouseInputSource* mi = mouseSources.begin(), * const e = mouseSources.end(); mi != e; ++mi)
|
||||
for (auto& ms : Desktop::getInstance().getMouseSources())
|
||||
{
|
||||
Component* const c = mi->getComponentUnderMouse();
|
||||
auto* c = ms.getComponentUnderMouse();
|
||||
|
||||
if ((c == this || (includeChildren && isParentOf (c)))
|
||||
&& c->reallyContains (c->getLocalPoint (nullptr, mi->getScreenPosition()).roundToInt(), false)
|
||||
&& (mi->isMouse() || mi->isDragging()))
|
||||
&& c->reallyContains (c->getLocalPoint (nullptr, ms.getScreenPosition()).roundToInt(), false)
|
||||
&& ((! ms.isTouch()) || ms.isDragging()))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -2984,10 +2994,8 @@ bool Component::isMouseOver (const bool includeChildren) const
|
|||
|
||||
bool Component::isMouseButtonDown() const
|
||||
{
|
||||
const Array<MouseInputSource>& mouseSources = Desktop::getInstance().getMouseSources();
|
||||
|
||||
for (MouseInputSource* mi = mouseSources.begin(), * const e = mouseSources.end(); mi != e; ++mi)
|
||||
if (mi->isDragging() && mi->getComponentUnderMouse() == this)
|
||||
for (auto& ms : Desktop::getInstance().getMouseSources())
|
||||
if (ms.isDragging() && ms.getComponentUnderMouse() == this)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
@ -2995,14 +3003,12 @@ bool Component::isMouseButtonDown() const
|
|||
|
||||
bool Component::isMouseOverOrDragging (const bool includeChildren) const
|
||||
{
|
||||
const Array<MouseInputSource>& mouseSources = Desktop::getInstance().getMouseSources();
|
||||
|
||||
for (MouseInputSource* mi = mouseSources.begin(), * const e = mouseSources.end(); mi != e; ++mi)
|
||||
for (auto& ms : Desktop::getInstance().getMouseSources())
|
||||
{
|
||||
Component* const c = mi->getComponentUnderMouse();
|
||||
auto* c = ms.getComponentUnderMouse();
|
||||
|
||||
if ((c == this || (includeChildren && isParentOf (c)))
|
||||
&& (mi->isMouse() || mi->isDragging()))
|
||||
&& ((! ms.isTouch()) || ms.isDragging()))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2299,9 +2299,9 @@ private:
|
|||
//==============================================================================
|
||||
void internalMouseEnter (MouseInputSource, Point<float>, Time);
|
||||
void internalMouseExit (MouseInputSource, Point<float>, Time);
|
||||
void internalMouseDown (MouseInputSource, Point<float>, Time, float);
|
||||
void internalMouseUp (MouseInputSource, Point<float>, Time, const ModifierKeys oldModifiers, float);
|
||||
void internalMouseDrag (MouseInputSource, Point<float>, Time, float);
|
||||
void internalMouseDown (MouseInputSource, Point<float>, Time, float, float, float, float, float);
|
||||
void internalMouseUp (MouseInputSource, Point<float>, Time, const ModifierKeys oldModifiers, float, float, float, float, float);
|
||||
void internalMouseDrag (MouseInputSource, Point<float>, Time, float, float, float, float, float);
|
||||
void internalMouseMove (MouseInputSource, Point<float>, Time);
|
||||
void internalMouseWheel (MouseInputSource, Point<float>, Time, const MouseWheelDetails&);
|
||||
void internalMagnifyGesture (MouseInputSource, Point<float>, Time, float);
|
||||
|
|
|
|||
|
|
@ -240,14 +240,16 @@ void Desktop::sendMouseMove()
|
|||
|
||||
lastFakeMouseMove = getMousePositionFloat();
|
||||
|
||||
if (Component* const target = findComponentAt (lastFakeMouseMove.roundToInt()))
|
||||
if (auto* target = findComponentAt (lastFakeMouseMove.roundToInt()))
|
||||
{
|
||||
Component::BailOutChecker checker (target);
|
||||
const Point<float> pos (target->getLocalPoint (nullptr, lastFakeMouseMove));
|
||||
const Time now (Time::getCurrentTime());
|
||||
|
||||
const MouseEvent me (getMainMouseSource(), pos, ModifierKeys::getCurrentModifiers(),
|
||||
MouseInputSource::invalidPressure, target, target, now, pos, now, 0, false);
|
||||
const MouseEvent me (getMainMouseSource(), pos, ModifierKeys::getCurrentModifiers(), MouseInputSource::invalidPressure,
|
||||
MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation,
|
||||
MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY,
|
||||
target, target, now, pos, now, 0, false);
|
||||
|
||||
if (me.mods.isAnyMouseButtonDown())
|
||||
mouseListeners.callChecked (checker, &MouseListener::mouseDrag, me);
|
||||
|
|
|
|||
|
|
@ -120,6 +120,7 @@ class MarkerList;
|
|||
class RelativeRectangle;
|
||||
class MouseEvent;
|
||||
struct MouseWheelDetails;
|
||||
struct PenDetails;
|
||||
class ToggleButton;
|
||||
class TextButton;
|
||||
class AlertWindow;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ MouseEvent::MouseEvent (MouseInputSource inputSource,
|
|||
Point<float> pos,
|
||||
ModifierKeys modKeys,
|
||||
float force,
|
||||
float o, float r,
|
||||
float tX, float tY,
|
||||
Component* const eventComp,
|
||||
Component* const originator,
|
||||
Time time,
|
||||
|
|
@ -38,6 +40,8 @@ MouseEvent::MouseEvent (MouseInputSource inputSource,
|
|||
y (roundToInt (pos.y)),
|
||||
mods (modKeys),
|
||||
pressure (force),
|
||||
orientation (o), rotation (r),
|
||||
tiltX (tX), tiltY (tY),
|
||||
eventComponent (eventComp),
|
||||
originalComponent (originator),
|
||||
eventTime (time),
|
||||
|
|
@ -59,23 +63,24 @@ MouseEvent MouseEvent::getEventRelativeTo (Component* const otherComponent) cons
|
|||
jassert (otherComponent != nullptr);
|
||||
|
||||
return MouseEvent (source, otherComponent->getLocalPoint (eventComponent, position),
|
||||
mods, pressure, otherComponent, originalComponent, eventTime,
|
||||
mods, pressure, orientation, rotation, tiltX, tiltY,
|
||||
otherComponent, originalComponent, eventTime,
|
||||
otherComponent->getLocalPoint (eventComponent, mouseDownPos),
|
||||
mouseDownTime, numberOfClicks, wasMovedSinceMouseDown != 0);
|
||||
}
|
||||
|
||||
MouseEvent MouseEvent::withNewPosition (Point<float> newPosition) const noexcept
|
||||
{
|
||||
return MouseEvent (source, newPosition, mods, pressure, eventComponent,
|
||||
originalComponent, eventTime, mouseDownPos, mouseDownTime,
|
||||
return MouseEvent (source, newPosition, mods, pressure, orientation, rotation, tiltX, tiltY,
|
||||
eventComponent, originalComponent, eventTime, mouseDownPos, mouseDownTime,
|
||||
numberOfClicks, wasMovedSinceMouseDown != 0);
|
||||
}
|
||||
|
||||
MouseEvent MouseEvent::withNewPosition (Point<int> newPosition) const noexcept
|
||||
{
|
||||
return MouseEvent (source, newPosition.toFloat(), mods, pressure, eventComponent,
|
||||
originalComponent, eventTime, mouseDownPos, mouseDownTime,
|
||||
numberOfClicks, wasMovedSinceMouseDown != 0);
|
||||
return MouseEvent (source, newPosition.toFloat(), mods, pressure, orientation, rotation,
|
||||
tiltX, tiltY, eventComponent, originalComponent, eventTime, mouseDownPos,
|
||||
mouseDownTime, numberOfClicks, wasMovedSinceMouseDown != 0);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -120,6 +125,9 @@ int MouseEvent::getMouseDownScreenX() const { return getMous
|
|||
int MouseEvent::getMouseDownScreenY() const { return getMouseDownScreenPosition().y; }
|
||||
|
||||
bool MouseEvent::isPressureValid() const noexcept { return pressure > 0.0f && pressure < 1.0f; }
|
||||
bool MouseEvent::isOrientationValid() const noexcept { return orientation >= 0.0f && orientation <= 2.0f * float_Pi; }
|
||||
bool MouseEvent::isRotationValid() const noexcept { return rotation >= 0 && rotation <= 2.0f * float_Pi; }
|
||||
bool MouseEvent::isTiltValid (bool isX) const noexcept { return isX ? (tiltX >= -1.0f && tiltX <= 1.0f) : (tiltY >= -1.0f && tiltY <= 1.0f); }
|
||||
|
||||
//==============================================================================
|
||||
static int doubleClickTimeOutMs = 400;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Contains position and status information about a mouse event.
|
||||
|
|
@ -46,6 +45,10 @@ public:
|
|||
@param pressure the pressure of the touch or stylus, in the range 0 to 1. Devices that
|
||||
do not support force information may return 0.0, 1.0, or a negative value,
|
||||
depending on the platform
|
||||
@param orientation the orientation of the touch input for this event in radians. The default is 0
|
||||
@param rotation the rotation of the pen device for this event in radians. The default is 0
|
||||
@param tiltX the tilt of the pen device along the x-axis between -1.0 and 1.0. The default is 0
|
||||
@param tiltY the tilt of the pen device along the y-axis between -1.0 and 1.0. The default is 0
|
||||
@param eventComponent the component that the mouse event applies to
|
||||
@param originator the component that originally received the event
|
||||
@param eventTime the time the event happened
|
||||
|
|
@ -62,6 +65,8 @@ public:
|
|||
Point<float> position,
|
||||
ModifierKeys modifiers,
|
||||
float pressure,
|
||||
float orientation, float rotation,
|
||||
float tiltX, float tiltY,
|
||||
Component* eventComponent,
|
||||
Component* originator,
|
||||
Time eventTime,
|
||||
|
|
@ -117,7 +122,27 @@ public:
|
|||
If the input device doesn't provide any pressure data, it may return a negative
|
||||
value here, or 0.0 or 1.0, depending on the platform.
|
||||
*/
|
||||
float pressure;
|
||||
const float pressure;
|
||||
|
||||
/** The orientation of the touch input for this event in radians where 0 indicates a touch aligned with the x-axis
|
||||
and pointing from left to right; increasing values indicate rotation in the clockwise direction. The default is 0.
|
||||
*/
|
||||
const float orientation;
|
||||
|
||||
/** The rotation of the pen device for this event in radians. Indicates the clockwise
|
||||
rotation, or twist, of the pen. The default is 0.
|
||||
*/
|
||||
const float rotation;
|
||||
|
||||
/** The tilt of the pen device along the x-axis between -1.0 and 1.0. A positive value indicates
|
||||
a tilt to the right. The default is 0.
|
||||
*/
|
||||
const float tiltX;
|
||||
|
||||
/** The tilt of the pen device along the y-axis between -1.0 and 1.0. A positive value indicates
|
||||
a tilt toward the user. The default is 0.
|
||||
*/
|
||||
const float tiltY;
|
||||
|
||||
/** The component that this event applies to.
|
||||
|
||||
|
|
@ -239,6 +264,15 @@ public:
|
|||
/** Returns true if the pressure value for this event is meaningful. */
|
||||
bool isPressureValid() const noexcept;
|
||||
|
||||
/** Returns true if the orientation value for this event is meaningful. */
|
||||
bool isOrientationValid() const noexcept;
|
||||
|
||||
/** Returns true if the rotation value for this event is meaningful. */
|
||||
bool isRotationValid() const noexcept;
|
||||
|
||||
/** Returns true if the current tilt value (either x- or y-axis) is meaningful. */
|
||||
bool isTiltValid (bool tiltX) const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** The position of the mouse when the event occurred.
|
||||
|
||||
|
|
@ -374,3 +408,30 @@ struct MouseWheelDetails
|
|||
the wheel being released. */
|
||||
bool isInertial;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Contains status information about a pen event.
|
||||
|
||||
@see MouseListener, MouseEvent
|
||||
*/
|
||||
struct PenDetails
|
||||
{
|
||||
/**
|
||||
The rotation of the pen device in radians. Indicates the clockwise rotation, or twist,
|
||||
of the pen. The default is 0.
|
||||
*/
|
||||
float rotation;
|
||||
|
||||
/**
|
||||
Indicates the angle of tilt of the pointer in a range of -1.0 to 1.0 along the x-axis where
|
||||
a positive value indicates a tilt to the right. The default is 0.
|
||||
*/
|
||||
float tiltX;
|
||||
|
||||
/**
|
||||
Indicates the angle of tilt of the pointer in a range of -1.0 to 1.0 along the y-axis where
|
||||
a positive value indicates a tilt toward the user. The default is 0.
|
||||
*/
|
||||
float tiltY;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -26,11 +26,10 @@ class MouseInputSourceInternal : private AsyncUpdater
|
|||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
MouseInputSourceInternal (const int i, const bool isMouse)
|
||||
: index (i), isMouseDevice (isMouse), pressure (0.0f),
|
||||
isUnboundedMouseModeOn (false), isCursorVisibleUntilOffscreen (false),
|
||||
lastPeer (nullptr), currentCursorHandle (nullptr),
|
||||
mouseEventCounter (0), mouseMovedSignificantlySincePressed (false)
|
||||
MouseInputSourceInternal (const int i, const MouseInputSource::InputSourceType type)
|
||||
: index (i), inputType (type), pressure (0.0f), orientation (0.0f), rotation (0.0f), tiltX (0.0f), tiltY (0.0f),
|
||||
isUnboundedMouseModeOn (false), isCursorVisibleUntilOffscreen (false), lastPeer (nullptr),
|
||||
currentCursorHandle (nullptr), mouseEventCounter (0), mouseMovedSignificantlySincePressed (false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -93,8 +92,8 @@ public:
|
|||
// This needs to return the live position if possible, but it mustn't update the lastScreenPos
|
||||
// value, because that can cause continuity problems.
|
||||
return ScalingHelpers::unscaledScreenPosToScaled
|
||||
(unboundedMouseOffset + (isMouseDevice ? MouseInputSource::getCurrentRawMousePosition()
|
||||
: lastScreenPos));
|
||||
(unboundedMouseOffset + (inputType != MouseInputSource::InputSourceType::touch ? MouseInputSource::getCurrentRawMousePosition()
|
||||
: lastScreenPos));
|
||||
}
|
||||
|
||||
void setScreenPosition (Point<float> p)
|
||||
|
|
@ -102,11 +101,15 @@ public:
|
|||
MouseInputSource::setRawMousePosition (ScalingHelpers::scaledScreenPosToUnscaled (p));
|
||||
}
|
||||
|
||||
bool isPressureValid() const noexcept { return pressure > 0.0f && pressure < 1.0f; }
|
||||
bool isPressureValid() const noexcept { return pressure >= 0.0f && pressure <= 1.0f; }
|
||||
bool isOrientationValid() const noexcept { return orientation >= 0.0f && orientation <= 2.0f * float_Pi; }
|
||||
bool isRotationValid() const noexcept { return rotation >= 0.0f && rotation <= 2.0f * float_Pi; }
|
||||
bool isTiltValid (bool isX) const noexcept { return isX ? (tiltX >= -1.0f && tiltX <= 1.0f) : (tiltY >= -1.0f && tiltY <= 1.0f); }
|
||||
|
||||
//==============================================================================
|
||||
#if JUCE_DUMP_MOUSE_EVENTS
|
||||
#define JUCE_MOUSE_EVENT_DBG(desc) DBG ("Mouse " << desc << " #" << index \
|
||||
#define JUCE_MOUSE_EVENT_
|
||||
(desc) DBG ("Mouse " << desc << " #" << index \
|
||||
<< ": " << screenPosToLocalPos (comp, screenPos).toString() \
|
||||
<< " - Comp: " << String::toHexString ((pointer_sized_int) &comp));
|
||||
#else
|
||||
|
|
@ -134,19 +137,19 @@ public:
|
|||
void sendMouseDown (Component& comp, Point<float> screenPos, Time time)
|
||||
{
|
||||
JUCE_MOUSE_EVENT_DBG ("down")
|
||||
comp.internalMouseDown (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time, pressure);
|
||||
comp.internalMouseDown (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time, pressure, orientation, rotation, tiltX, tiltY);
|
||||
}
|
||||
|
||||
void sendMouseDrag (Component& comp, Point<float> screenPos, Time time)
|
||||
{
|
||||
JUCE_MOUSE_EVENT_DBG ("drag")
|
||||
comp.internalMouseDrag (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time, pressure);
|
||||
comp.internalMouseDrag (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time, pressure, orientation, rotation, tiltX, tiltY);
|
||||
}
|
||||
|
||||
void sendMouseUp (Component& comp, Point<float> screenPos, Time time, const ModifierKeys oldMods)
|
||||
{
|
||||
JUCE_MOUSE_EVENT_DBG ("up")
|
||||
comp.internalMouseUp (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time, oldMods, pressure);
|
||||
comp.internalMouseUp (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time, oldMods, pressure, orientation, rotation, tiltX, tiltY);
|
||||
}
|
||||
|
||||
void sendMouseWheel (Component& comp, Point<float> screenPos, Time time, const MouseWheelDetails& wheel)
|
||||
|
|
@ -290,17 +293,32 @@ public:
|
|||
|
||||
//==============================================================================
|
||||
void handleEvent (ComponentPeer& newPeer, Point<float> positionWithinPeer, Time time,
|
||||
const ModifierKeys newMods, float newPressure)
|
||||
const ModifierKeys newMods, float newPressure, float newOrientation, PenDetails pen)
|
||||
{
|
||||
lastTime = time;
|
||||
|
||||
const bool pressureChanged = (pressure != newPressure);
|
||||
pressure = newPressure;
|
||||
|
||||
const bool orientationChanged = (orientation != newOrientation);
|
||||
orientation = newOrientation;
|
||||
|
||||
const bool rotationChanged = (rotation != pen.rotation);
|
||||
rotation = pen.rotation;
|
||||
|
||||
const bool tiltChanged = (tiltX != pen.tiltX || tiltY != pen.tiltY);
|
||||
tiltX = pen.tiltX;
|
||||
tiltY = pen.tiltY;
|
||||
|
||||
const bool shouldUpdate = (pressureChanged || orientationChanged || rotationChanged || tiltChanged);
|
||||
|
||||
++mouseEventCounter;
|
||||
|
||||
const Point<float> screenPos (newPeer.localToGlobal (positionWithinPeer));
|
||||
|
||||
if (isDragging() && newMods.isAnyMouseButtonDown())
|
||||
{
|
||||
setScreenPos (screenPos, time, pressureChanged);
|
||||
setScreenPos (screenPos, time, shouldUpdate);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -314,7 +332,7 @@ public:
|
|||
peer = getPeer();
|
||||
|
||||
if (peer != nullptr)
|
||||
setScreenPos (screenPos, time, pressureChanged);
|
||||
setScreenPos (screenPos, time, shouldUpdate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -475,10 +493,14 @@ public:
|
|||
|
||||
//==============================================================================
|
||||
const int index;
|
||||
const bool isMouseDevice;
|
||||
const MouseInputSource::InputSourceType inputType;
|
||||
Point<float> lastScreenPos, unboundedMouseOffset; // NB: these are unscaled coords
|
||||
ModifierKeys buttonState;
|
||||
float pressure;
|
||||
float orientation;
|
||||
float rotation;
|
||||
float tiltX;
|
||||
float tiltY;
|
||||
|
||||
bool isUnboundedMouseModeOn, isCursorVisibleUntilOffscreen;
|
||||
|
||||
|
|
@ -551,36 +573,43 @@ MouseInputSource& MouseInputSource::operator= (const MouseInputSource& other) no
|
|||
return *this;
|
||||
}
|
||||
|
||||
bool MouseInputSource::isMouse() const noexcept { return pimpl->isMouseDevice; }
|
||||
bool MouseInputSource::isTouch() const noexcept { return ! isMouse(); }
|
||||
bool MouseInputSource::canHover() const noexcept { return isMouse(); }
|
||||
bool MouseInputSource::hasMouseWheel() const noexcept { return isMouse(); }
|
||||
int MouseInputSource::getIndex() const noexcept { return pimpl->index; }
|
||||
bool MouseInputSource::isDragging() const noexcept { return pimpl->isDragging(); }
|
||||
Point<float> MouseInputSource::getScreenPosition() const noexcept { return pimpl->getScreenPosition(); }
|
||||
ModifierKeys MouseInputSource::getCurrentModifiers() const noexcept { return pimpl->getCurrentModifiers(); }
|
||||
float MouseInputSource::getCurrentPressure() const noexcept { return pimpl->pressure; }
|
||||
bool MouseInputSource::isPressureValid() const noexcept { return pimpl->isPressureValid(); }
|
||||
Component* MouseInputSource::getComponentUnderMouse() const { return pimpl->getComponentUnderMouse(); }
|
||||
void MouseInputSource::triggerFakeMove() const { pimpl->triggerFakeMove(); }
|
||||
int MouseInputSource::getNumberOfMultipleClicks() const noexcept { return pimpl->getNumberOfMultipleClicks(); }
|
||||
Time MouseInputSource::getLastMouseDownTime() const noexcept { return pimpl->getLastMouseDownTime(); }
|
||||
Point<float> MouseInputSource::getLastMouseDownPosition() const noexcept { return pimpl->getLastMouseDownPosition(); }
|
||||
MouseInputSource::InputSourceType MouseInputSource::getType() const noexcept { return pimpl->inputType; }
|
||||
bool MouseInputSource::isTouch() const noexcept { return (getType() == MouseInputSource::InputSourceType::touch); }
|
||||
bool MouseInputSource::canHover() const noexcept { return ! isTouch(); }
|
||||
bool MouseInputSource::hasMouseWheel() const noexcept { return ! isTouch(); }
|
||||
int MouseInputSource::getIndex() const noexcept { return pimpl->index; }
|
||||
bool MouseInputSource::isDragging() const noexcept { return pimpl->isDragging(); }
|
||||
Point<float> MouseInputSource::getScreenPosition() const noexcept { return pimpl->getScreenPosition(); }
|
||||
ModifierKeys MouseInputSource::getCurrentModifiers() const noexcept { return pimpl->getCurrentModifiers(); }
|
||||
float MouseInputSource::getCurrentPressure() const noexcept { return pimpl->pressure; }
|
||||
bool MouseInputSource::isPressureValid() const noexcept { return pimpl->isPressureValid(); }
|
||||
float MouseInputSource::getCurrentOrientation() const noexcept { return pimpl->orientation; }
|
||||
bool MouseInputSource::isOrientationValid() const noexcept { return pimpl->isOrientationValid(); }
|
||||
float MouseInputSource::getCurrentRotation() const noexcept { return pimpl->rotation; }
|
||||
bool MouseInputSource::isRotationValid() const noexcept { return pimpl->isRotationValid(); }
|
||||
float MouseInputSource::getCurrentTilt (bool tiltX) const noexcept { return tiltX ? pimpl->tiltX : pimpl->tiltY; }
|
||||
bool MouseInputSource::isTiltValid (bool isX) const noexcept { return pimpl->isTiltValid (isX); }
|
||||
Component* MouseInputSource::getComponentUnderMouse() const { return pimpl->getComponentUnderMouse(); }
|
||||
void MouseInputSource::triggerFakeMove() const { pimpl->triggerFakeMove(); }
|
||||
int MouseInputSource::getNumberOfMultipleClicks() const noexcept { return pimpl->getNumberOfMultipleClicks(); }
|
||||
Time MouseInputSource::getLastMouseDownTime() const noexcept { return pimpl->getLastMouseDownTime(); }
|
||||
Point<float> MouseInputSource::getLastMouseDownPosition() const noexcept { return pimpl->getLastMouseDownPosition(); }
|
||||
bool MouseInputSource::hasMouseMovedSignificantlySincePressed() const noexcept { return pimpl->hasMouseMovedSignificantlySincePressed(); }
|
||||
bool MouseInputSource::canDoUnboundedMovement() const noexcept { return isMouse(); }
|
||||
bool MouseInputSource::canDoUnboundedMovement() const noexcept { return ! isTouch(); }
|
||||
void MouseInputSource::enableUnboundedMouseMovement (bool isEnabled, bool keepCursorVisibleUntilOffscreen) const
|
||||
{ pimpl->enableUnboundedMouseMovement (isEnabled, keepCursorVisibleUntilOffscreen); }
|
||||
bool MouseInputSource::isUnboundedMouseMovementEnabled() const { return pimpl->isUnboundedMouseModeOn; }
|
||||
bool MouseInputSource::hasMouseCursor() const noexcept { return isMouse(); }
|
||||
bool MouseInputSource::hasMouseCursor() const noexcept { return ! isTouch(); }
|
||||
void MouseInputSource::showMouseCursor (const MouseCursor& cursor) { pimpl->showMouseCursor (cursor, false); }
|
||||
void MouseInputSource::hideCursor() { pimpl->hideCursor(); }
|
||||
void MouseInputSource::revealCursor() { pimpl->revealCursor (false); }
|
||||
void MouseInputSource::forceMouseCursorUpdate() { pimpl->revealCursor (true); }
|
||||
void MouseInputSource::setScreenPosition (Point<float> p) { pimpl->setScreenPosition (p); }
|
||||
|
||||
void MouseInputSource::handleEvent (ComponentPeer& peer, Point<float> pos, int64 time, ModifierKeys mods, float pressure)
|
||||
void MouseInputSource::handleEvent (ComponentPeer& peer, Point<float> pos, int64 time, ModifierKeys mods,
|
||||
float pressure, float orientation, const PenDetails& pen)
|
||||
{
|
||||
pimpl->handleEvent (peer, pos, Time (time), mods.withOnlyMouseButtons(), pressure);
|
||||
pimpl->handleEvent (peer, pos, Time (time), mods.withOnlyMouseButtons(), pressure, orientation, pen);
|
||||
}
|
||||
|
||||
void MouseInputSource::handleWheel (ComponentPeer& peer, Point<float> pos, int64 time, const MouseWheelDetails& wheel)
|
||||
|
|
@ -594,22 +623,30 @@ void MouseInputSource::handleMagnifyGesture (ComponentPeer& peer, Point<float> p
|
|||
}
|
||||
|
||||
const float MouseInputSource::invalidPressure = 0.0f;
|
||||
const float MouseInputSource::invalidOrientation = 0.0f;
|
||||
const float MouseInputSource::invalidRotation = 0.0f;
|
||||
|
||||
const float MouseInputSource::invalidTiltX = 0.0f;
|
||||
const float MouseInputSource::invalidTiltY = 0.0f;
|
||||
|
||||
//==============================================================================
|
||||
struct MouseInputSource::SourceList : public Timer
|
||||
{
|
||||
SourceList()
|
||||
{
|
||||
addSource();
|
||||
addSource (0, MouseInputSource::InputSourceType::mouse);
|
||||
}
|
||||
|
||||
bool addSource();
|
||||
bool canUseTouch();
|
||||
|
||||
void addSource (int index, bool isMouse)
|
||||
MouseInputSource* addSource (int index, MouseInputSource::InputSourceType type)
|
||||
{
|
||||
MouseInputSourceInternal* s = new MouseInputSourceInternal (index, isMouse);
|
||||
auto* s = new MouseInputSourceInternal (index, type);
|
||||
sources.add (s);
|
||||
sourceArray.add (MouseInputSource (s));
|
||||
|
||||
return &sourceArray.getReference (sourceArray.size() - 1);
|
||||
}
|
||||
|
||||
MouseInputSource* getMouseSource (int index) const noexcept
|
||||
|
|
@ -618,21 +655,29 @@ struct MouseInputSource::SourceList : public Timer
|
|||
: nullptr;
|
||||
}
|
||||
|
||||
MouseInputSource* getOrCreateMouseInputSource (int touchIndex)
|
||||
MouseInputSource* getOrCreateMouseInputSource (MouseInputSource::InputSourceType type, int touchIndex = 0)
|
||||
{
|
||||
jassert (touchIndex >= 0 && touchIndex < 100); // sanity-check on number of fingers
|
||||
|
||||
for (;;)
|
||||
if (type == MouseInputSource::InputSourceType::mouse || type == MouseInputSource::InputSourceType::pen)
|
||||
{
|
||||
if (MouseInputSource* mouse = getMouseSource (touchIndex))
|
||||
return mouse;
|
||||
for (auto& m : sourceArray)
|
||||
if (type == m.getType())
|
||||
return &m;
|
||||
|
||||
if (! addSource())
|
||||
{
|
||||
jassertfalse; // not enough mouse sources!
|
||||
return nullptr;
|
||||
}
|
||||
addSource (0, type);
|
||||
}
|
||||
else if (type == MouseInputSource::InputSourceType::touch)
|
||||
{
|
||||
jassert (touchIndex >= 0 && touchIndex < 100); // sanity-check on number of fingers
|
||||
|
||||
for (auto& m : sourceArray)
|
||||
if (type == m.getType() && touchIndex == m.getIndex())
|
||||
return &m;
|
||||
|
||||
if (canUseTouch())
|
||||
return addSource (touchIndex, type);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int getNumDraggingMouseSources() const noexcept
|
||||
|
|
|
|||
|
|
@ -48,6 +48,14 @@
|
|||
class JUCE_API MouseInputSource
|
||||
{
|
||||
public:
|
||||
/** Possible mouse input sources */
|
||||
enum InputSourceType
|
||||
{
|
||||
mouse,
|
||||
touch,
|
||||
pen
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
MouseInputSource (const MouseInputSource&) noexcept;
|
||||
MouseInputSource& operator= (const MouseInputSource&) noexcept;
|
||||
|
|
@ -58,10 +66,9 @@ public:
|
|||
bool operator!= (const MouseInputSource& other) const noexcept { return pimpl != other.pimpl; }
|
||||
|
||||
//==============================================================================
|
||||
/** Returns true if this object represents a normal desk-based mouse device. */
|
||||
bool isMouse() const noexcept;
|
||||
/** Returns the type of input source that this object represents */
|
||||
MouseInputSource::InputSourceType getType() const noexcept;
|
||||
|
||||
/** Returns true if this object represents a source of touch events - i.e. a finger or stylus. */
|
||||
bool isTouch() const noexcept;
|
||||
|
||||
/** Returns true if this source has an on-screen pointer that can hover over
|
||||
|
|
@ -101,9 +108,35 @@ public:
|
|||
*/
|
||||
float getCurrentPressure() const noexcept;
|
||||
|
||||
/** Returns the device's current orientation in radians. 0 indicates a touch pointer
|
||||
aligned with the x-axis and pointing from left to right; increasing values indicate
|
||||
rotation in the clockwise direction. Only reported by a touch pointer.
|
||||
*/
|
||||
float getCurrentOrientation() const noexcept;
|
||||
|
||||
/** Returns the device's current rotation. Indicates the clockwise rotation, or twist, of the pointer
|
||||
in radians. The default is 0. Only reported by a pen pointer.
|
||||
*/
|
||||
float getCurrentRotation() const noexcept;
|
||||
|
||||
/** Returns the angle of tilt of the pointer in a range of -1.0 to 1.0 either in the x- or y-axis. The default is 0.
|
||||
If x-axis, a positive value indicates a tilt to the right and if y-axis, a positive value indicates a tilt toward the user.
|
||||
Only reported by a pen pointer.
|
||||
*/
|
||||
float getCurrentTilt (bool tiltX) const noexcept;
|
||||
|
||||
/** Returns true if the current pressure value is meaningful. */
|
||||
bool isPressureValid() const noexcept;
|
||||
|
||||
/** Returns true if the current orientation value is meaningful. */
|
||||
bool isOrientationValid() const noexcept;
|
||||
|
||||
/** Returns true if the current rotation value is meaningful. */
|
||||
bool isRotationValid() const noexcept;
|
||||
|
||||
/** Returns true if the current tilt value (either x- or y-axis) is meaningful. */
|
||||
bool isTiltValid (bool tiltX) const noexcept;
|
||||
|
||||
/** Returns the component that was last known to be under this pointer. */
|
||||
Component* getComponentUnderMouse() const;
|
||||
|
||||
|
|
@ -178,6 +211,16 @@ public:
|
|||
*/
|
||||
static const float invalidPressure;
|
||||
|
||||
/** A default value for orientation, which is used when a device doesn't support it */
|
||||
static const float invalidOrientation;
|
||||
|
||||
/** A default value for rotation, which is used when a device doesn't support it */
|
||||
static const float invalidRotation;
|
||||
|
||||
/** Default values for tilt, which are used when a device doesn't support it */
|
||||
static const float invalidTiltX;
|
||||
static const float invalidTiltY;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
friend class ComponentPeer;
|
||||
|
|
@ -188,7 +231,7 @@ private:
|
|||
struct SourceList;
|
||||
|
||||
explicit MouseInputSource (MouseInputSourceInternal*) noexcept;
|
||||
void handleEvent (ComponentPeer&, Point<float>, int64 time, ModifierKeys, float);
|
||||
void handleEvent (ComponentPeer&, Point<float>, int64 time, ModifierKeys, float, float, const PenDetails&);
|
||||
void handleWheel (ComponentPeer&, Point<float>, int64 time, const MouseWheelDetails&);
|
||||
void handleMagnifyGesture (ComponentPeer&, Point<float>, int64 time, float scaleFactor);
|
||||
|
||||
|
|
|
|||
|
|
@ -392,7 +392,8 @@ public:
|
|||
lastMousePos = pos;
|
||||
|
||||
// this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before.
|
||||
handleMouseEvent (index, pos, currentModifiers.withoutMouseButtons(), MouseInputSource::invalidPressure, time);
|
||||
handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, currentModifiers.withoutMouseButtons(),
|
||||
MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, time, {}, index);
|
||||
|
||||
if (isValidPeer (this))
|
||||
handleMouseDragCallback (index, sysPos, time);
|
||||
|
|
@ -406,8 +407,8 @@ public:
|
|||
jassert (index < 64);
|
||||
touchesDown = (touchesDown | (1 << (index & 63)));
|
||||
currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier);
|
||||
handleMouseEvent (index, pos, currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier),
|
||||
MouseInputSource::invalidPressure, time);
|
||||
handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier),
|
||||
MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, time, {}, index);
|
||||
}
|
||||
|
||||
void handleMouseUpCallback (int index, Point<float> pos, int64 time)
|
||||
|
|
@ -421,7 +422,8 @@ public:
|
|||
if (touchesDown == 0)
|
||||
currentModifiers = currentModifiers.withoutMouseButtons();
|
||||
|
||||
handleMouseEvent (index, pos, currentModifiers.withoutMouseButtons(), MouseInputSource::invalidPressure, time);
|
||||
handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, currentModifiers.withoutMouseButtons(), MouseInputSource::invalidPressure,
|
||||
MouseInputSource::invalidOrientation, time, {}, index);
|
||||
}
|
||||
|
||||
void handleKeyDownCallback (int k, int kc)
|
||||
|
|
@ -682,7 +684,12 @@ Desktop::DisplayOrientation Desktop::getCurrentOrientation() const
|
|||
|
||||
bool MouseInputSource::SourceList::addSource()
|
||||
{
|
||||
addSource (sources.size(), false);
|
||||
addSource (sources.size(), MouseInputSource::InputSourceType::touch);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MouseInputSource::SourceList::canUseTouch()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -846,8 +846,8 @@ void UIViewComponentPeer::handleTouches (UIEvent* event, const bool isDown, cons
|
|||
modsToSend = currentModifiers;
|
||||
|
||||
// this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before.
|
||||
handleMouseEvent (touchIndex, pos, modsToSend.withoutMouseButtons(),
|
||||
MouseInputSource::invalidPressure, time);
|
||||
handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, modsToSend.withoutMouseButtons(),
|
||||
MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, time, {}, touchIndex);
|
||||
|
||||
if (! isValidPeer (this)) // (in case this component was deleted by the event)
|
||||
return;
|
||||
|
|
@ -874,15 +874,16 @@ void UIViewComponentPeer::handleTouches (UIEvent* event, const bool isDown, cons
|
|||
float pressure = maximumForce > 0 ? jlimit (0.0001f, 0.9999f, getTouchForce (touch) / maximumForce)
|
||||
: MouseInputSource::invalidPressure;
|
||||
|
||||
handleMouseEvent (touchIndex, pos, modsToSend, pressure, time);
|
||||
handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, modsToSend, pressure,
|
||||
MouseInputSource::invalidOrientation, time, { }, touchIndex);
|
||||
|
||||
if (! isValidPeer (this)) // (in case this component was deleted by the event)
|
||||
return;
|
||||
|
||||
if (isUp || isCancel)
|
||||
{
|
||||
handleMouseEvent (touchIndex, Point<float> (-1.0f, -1.0f),
|
||||
modsToSend, MouseInputSource::invalidPressure, time);
|
||||
handleMouseEvent (MouseInputSource::InputSourceType::touch, Point<float> (-1.0f, -1.0f), modsToSend,
|
||||
MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, time, {}, touchIndex);
|
||||
|
||||
if (! isValidPeer (this))
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -429,7 +429,12 @@ String SystemClipboard::getTextFromClipboard()
|
|||
//==============================================================================
|
||||
bool MouseInputSource::SourceList::addSource()
|
||||
{
|
||||
addSource (sources.size(), false);
|
||||
addSource (sources.size(), MouseInputSource::InputSourceType::touch);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MouseInputSource::SourceList::canUseTouch()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2157,15 +2157,16 @@ public:
|
|||
wheel.isSmooth = false;
|
||||
wheel.isInertial = false;
|
||||
|
||||
handleMouseWheel (0, getMousePos (buttonPressEvent), getEventTime (buttonPressEvent), wheel);
|
||||
handleMouseWheel (MouseInputSource::InputSourceType::mouse, getMousePos (buttonPressEvent),
|
||||
getEventTime (buttonPressEvent), wheel);
|
||||
}
|
||||
|
||||
void handleButtonPressEvent (const XButtonPressedEvent& buttonPressEvent, int buttonModifierFlag)
|
||||
{
|
||||
currentModifiers = currentModifiers.withFlags (buttonModifierFlag);
|
||||
toFront (true);
|
||||
handleMouseEvent (0, getMousePos (buttonPressEvent), currentModifiers,
|
||||
MouseInputSource::invalidPressure, getEventTime (buttonPressEvent));
|
||||
handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (buttonPressEvent), currentModifiers,
|
||||
MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, getEventTime (buttonPressEvent), {});
|
||||
}
|
||||
|
||||
void handleButtonPressEvent (const XButtonPressedEvent& buttonPressEvent)
|
||||
|
|
@ -2203,8 +2204,8 @@ public:
|
|||
if (dragState->dragging)
|
||||
handleExternalDragButtonReleaseEvent();
|
||||
|
||||
handleMouseEvent (0, getMousePos (buttonRelEvent), currentModifiers,
|
||||
MouseInputSource::invalidPressure, getEventTime (buttonRelEvent));
|
||||
handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (buttonRelEvent), currentModifiers,
|
||||
MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, getEventTime (buttonRelEvent));
|
||||
|
||||
clearLastMousePos();
|
||||
}
|
||||
|
|
@ -2218,8 +2219,8 @@ public:
|
|||
if (dragState->dragging)
|
||||
handleExternalDragMotionNotify();
|
||||
|
||||
handleMouseEvent (0, getMousePos (movedEvent), currentModifiers,
|
||||
MouseInputSource::invalidPressure, getEventTime (movedEvent));
|
||||
handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (movedEvent), currentModifiers,
|
||||
MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, getEventTime (movedEvent));
|
||||
}
|
||||
|
||||
void handleEnterNotifyEvent (const XEnterWindowEvent& enterEvent)
|
||||
|
|
@ -2232,8 +2233,8 @@ public:
|
|||
if (! currentModifiers.isAnyMouseButtonDown())
|
||||
{
|
||||
updateKeyModifiers ((int) enterEvent.state);
|
||||
handleMouseEvent (0, getMousePos (enterEvent), currentModifiers,
|
||||
MouseInputSource::invalidPressure, getEventTime (enterEvent));
|
||||
handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (enterEvent), currentModifiers,
|
||||
MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, getEventTime (enterEvent));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2246,8 +2247,8 @@ public:
|
|||
|| leaveEvent.mode == NotifyUngrab)
|
||||
{
|
||||
updateKeyModifiers ((int) leaveEvent.state);
|
||||
handleMouseEvent (0, getMousePos (leaveEvent), currentModifiers,
|
||||
MouseInputSource::invalidPressure, getEventTime (leaveEvent));
|
||||
handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (leaveEvent), currentModifiers,
|
||||
MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, getEventTime (leaveEvent));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3782,13 +3783,18 @@ bool MouseInputSource::SourceList::addSource()
|
|||
{
|
||||
if (sources.size() == 0)
|
||||
{
|
||||
addSource (0, true);
|
||||
addSource (0, MouseInputSource::InputSourceType::mouse);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MouseInputSource::SourceList::canUseTouch()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Desktop::canUseSemiTransparentWindows() noexcept
|
||||
{
|
||||
#if JUCE_USE_XRENDER
|
||||
|
|
|
|||
|
|
@ -585,8 +585,8 @@ public:
|
|||
sendMouseEvent (ev);
|
||||
else
|
||||
// moved into another window which overlaps this one, so trigger an exit
|
||||
handleMouseEvent (0, Point<float> (-1.0f, -1.0f), currentModifiers,
|
||||
getMousePressure (ev), getMouseTime (ev));
|
||||
handleMouseEvent (MouseInputSource::InputSourceType::mouse, { -1.0f, -1.0f }, currentModifiers,
|
||||
getMousePressure (ev), MouseInputSource::invalidOrientation, getMouseTime (ev));
|
||||
|
||||
showArrowCursorIfNeeded();
|
||||
}
|
||||
|
|
@ -658,7 +658,7 @@ public:
|
|||
wheel.deltaY = scale * (float) [ev deltaY];
|
||||
}
|
||||
|
||||
handleMouseWheel (0, getMousePos (ev, view), getMouseTime (ev), wheel);
|
||||
handleMouseWheel (MouseInputSource::InputSourceType::mouse, getMousePos (ev, view), getMouseTime (ev), wheel);
|
||||
}
|
||||
|
||||
void redirectMagnify (NSEvent* ev)
|
||||
|
|
@ -667,7 +667,7 @@ public:
|
|||
const float invScale = 1.0f - (float) [ev magnification];
|
||||
|
||||
if (invScale > 0.0f)
|
||||
handleMagnifyGesture (0, getMousePos (ev, view), getMouseTime (ev), 1.0f / invScale);
|
||||
handleMagnifyGesture (MouseInputSource::InputSourceType::mouse, getMousePos (ev, view), getMouseTime (ev), 1.0f / invScale);
|
||||
#endif
|
||||
ignoreUnused (ev);
|
||||
}
|
||||
|
|
@ -689,8 +689,8 @@ public:
|
|||
void sendMouseEvent (NSEvent* ev)
|
||||
{
|
||||
updateModifiers (ev);
|
||||
handleMouseEvent (0, getMousePos (ev, view), currentModifiers,
|
||||
getMousePressure (ev), getMouseTime (ev));
|
||||
handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (ev, view), currentModifiers,
|
||||
getMousePressure (ev), MouseInputSource::invalidOrientation, getMouseTime (ev));
|
||||
}
|
||||
|
||||
bool handleKeyEvent (NSEvent* ev, bool isKeyDown)
|
||||
|
|
@ -2046,13 +2046,18 @@ bool MouseInputSource::SourceList::addSource()
|
|||
{
|
||||
if (sources.size() == 0)
|
||||
{
|
||||
addSource (0, true);
|
||||
addSource (0, MouseInputSource::InputSourceType::mouse);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MouseInputSource::SourceList::canUseTouch()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void Desktop::setKioskComponent (Component* kioskComp, bool shouldBeEnabled, bool allowMenusAndBars)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -105,6 +105,26 @@ bool Desktop::canUseSemiTransparentWindows() noexcept
|
|||
|
||||
#endif
|
||||
|
||||
#ifndef WM_NCPOINTERUPDATE
|
||||
enum
|
||||
{
|
||||
WM_NCPOINTERUPDATE = 0x241,
|
||||
WM_NCPOINTERDOWN = 0x242,
|
||||
WM_NCPOINTERUP = 0x243,
|
||||
WM_POINTERUPDATE = 0x245,
|
||||
WM_POINTERDOWN = 0x246,
|
||||
WM_POINTERUP = 0x247,
|
||||
WM_POINTERENTER = 0x249,
|
||||
WM_POINTERLEAVE = 0x24A,
|
||||
WM_POINTERACTIVATE = 0x24B,
|
||||
WM_POINTERCAPTURECHANGED = 0x24C,
|
||||
WM_TOUCHHITTESTING = 0x24D,
|
||||
WM_POINTERWHEEL = 0x24E,
|
||||
WM_POINTERHWHEEL = 0x24F,
|
||||
WM_POINTERHITTEST = 0x250
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef MONITOR_DPI_TYPE
|
||||
enum Monitor_DPI_Type
|
||||
{
|
||||
|
|
@ -1530,7 +1550,7 @@ private:
|
|||
static bool isHWNDBlockedByModalComponents (HWND h)
|
||||
{
|
||||
for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;)
|
||||
if (Component* const c = Desktop::getInstance().getComponent (i))
|
||||
if (auto* c = Desktop::getInstance().getComponent (i))
|
||||
if ((! c->isCurrentlyBlockedByAnotherModalComponent())
|
||||
&& IsChild ((HWND) c->getWindowHandle(), h))
|
||||
return false;
|
||||
|
|
@ -1560,12 +1580,13 @@ private:
|
|||
case WM_NCMOUSEHOVER:
|
||||
case WM_MOUSEHOVER:
|
||||
case WM_TOUCH:
|
||||
#ifdef WM_POINTERUPDATE
|
||||
case WM_POINTERUPDATE:
|
||||
case WM_POINTERDOWN:
|
||||
case WM_NCPOINTERUPDATE:
|
||||
case WM_POINTERWHEEL:
|
||||
case WM_POINTERHWHEEL:
|
||||
case WM_POINTERUP:
|
||||
#endif
|
||||
return isHWNDBlockedByModalComponents (m.hwnd);
|
||||
case WM_POINTERACTIVATE:
|
||||
return isHWNDBlockedByModalComponents(m.hwnd);
|
||||
case WM_NCLBUTTONDOWN:
|
||||
case WM_NCLBUTTONDBLCLK:
|
||||
case WM_NCRBUTTONDOWN:
|
||||
|
|
@ -1580,9 +1601,11 @@ private:
|
|||
case WM_RBUTTONDBLCLK:
|
||||
case WM_KEYDOWN:
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_NCPOINTERDOWN:
|
||||
case WM_POINTERDOWN:
|
||||
if (isHWNDBlockedByModalComponents (m.hwnd))
|
||||
{
|
||||
if (Component* const modal = Component::getCurrentlyModalComponent (0))
|
||||
if (auto* modal = Component::getCurrentlyModalComponent (0))
|
||||
modal->inputAttemptWhenModal();
|
||||
|
||||
return true;
|
||||
|
|
@ -1955,9 +1978,9 @@ private:
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
void doMouseEvent (Point<float> position, float pressure)
|
||||
void doMouseEvent (Point<float> position, float pressure, float orientation = 0.0f, ModifierKeys mods = currentModifiers)
|
||||
{
|
||||
handleMouseEvent (0, position, currentModifiers, pressure, getMouseEventTime());
|
||||
handleMouseEvent (MouseInputSource::InputSourceType::mouse, position, mods, pressure, orientation, getMouseEventTime());
|
||||
}
|
||||
|
||||
StringArray getAvailableRenderingEngines() override
|
||||
|
|
@ -2018,10 +2041,22 @@ private:
|
|||
return (GetMessageExtraInfo() & 0xFFFFFF80 /*SIGNATURE_MASK*/) == 0xFF515780 /*MI_WP_SIGNATURE*/;
|
||||
}
|
||||
|
||||
static bool areOtherTouchSourcesActive()
|
||||
{
|
||||
for (auto& ms : Desktop::getInstance().getMouseSources())
|
||||
if (ms.isDragging() && (ms.getType() == MouseInputSource::InputSourceType::touch
|
||||
|| ms.getType() == MouseInputSource::InputSourceType::pen))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void doMouseMove (Point<float> position, bool isMouseDownEvent)
|
||||
{
|
||||
ModifierKeys modsToSend (currentModifiers);
|
||||
|
||||
// this will be handled by WM_TOUCH
|
||||
if (isTouchEvent())
|
||||
if (isTouchEvent() || areOtherTouchSourcesActive())
|
||||
return;
|
||||
|
||||
if (! isMouseOver)
|
||||
|
|
@ -2062,17 +2097,21 @@ private:
|
|||
static int minTimeBetweenMouses = getMinTimeBetweenMouseMoves();
|
||||
const uint32 now = Time::getMillisecondCounter();
|
||||
|
||||
if (! Desktop::getInstance().getMainMouseSource().isDragging())
|
||||
modsToSend = modsToSend.withoutMouseButtons();
|
||||
|
||||
if (now >= lastMouseTime + minTimeBetweenMouses)
|
||||
{
|
||||
lastMouseTime = now;
|
||||
doMouseEvent (position, MouseInputSource::invalidPressure);
|
||||
doMouseEvent (position, MouseInputSource::invalidPressure,
|
||||
MouseInputSource::invalidOrientation, modsToSend);
|
||||
}
|
||||
}
|
||||
|
||||
void doMouseDown (Point<float> position, const WPARAM wParam)
|
||||
{
|
||||
// this will be handled by WM_TOUCH
|
||||
if (isTouchEvent())
|
||||
if (isTouchEvent() || areOtherTouchSourcesActive())
|
||||
return;
|
||||
|
||||
if (GetCapture() != hwnd)
|
||||
|
|
@ -2098,7 +2137,7 @@ private:
|
|||
void doMouseUp (Point<float> position, const WPARAM wParam)
|
||||
{
|
||||
// this will be handled by WM_TOUCH
|
||||
if (isTouchEvent())
|
||||
if (isTouchEvent() || areOtherTouchSourcesActive())
|
||||
return;
|
||||
|
||||
updateModifiersFromWParam (wParam);
|
||||
|
|
@ -2138,7 +2177,9 @@ private:
|
|||
void doMouseExit()
|
||||
{
|
||||
isMouseOver = false;
|
||||
doMouseEvent (getCurrentMousePos(), MouseInputSource::invalidPressure);
|
||||
|
||||
if (! areOtherTouchSourcesActive())
|
||||
doMouseEvent (getCurrentMousePos(), MouseInputSource::invalidPressure);
|
||||
}
|
||||
|
||||
ComponentPeer* findPeerUnderMouse (Point<float>& localPos)
|
||||
|
|
@ -2157,6 +2198,19 @@ private:
|
|||
return peer;
|
||||
}
|
||||
|
||||
static MouseInputSource::InputSourceType getPointerType (WPARAM wParam)
|
||||
{
|
||||
#ifdef WM_POINTERWHEEL
|
||||
POINTER_INPUT_TYPE pointerType;
|
||||
|
||||
if (GetPointerType (GET_POINTERID_WPARAM (wParam), &pointerType))
|
||||
if (pointerType == 3)
|
||||
return MouseInputSource::InputSourceType::pen;
|
||||
#endif
|
||||
|
||||
return MouseInputSource::InputSourceType::mouse;
|
||||
}
|
||||
|
||||
void doMouseWheel (const WPARAM wParam, const bool isVertical)
|
||||
{
|
||||
updateKeyModifiers();
|
||||
|
|
@ -2170,8 +2224,8 @@ private:
|
|||
wheel.isInertial = false;
|
||||
|
||||
Point<float> localPos;
|
||||
if (ComponentPeer* const peer = findPeerUnderMouse (localPos))
|
||||
peer->handleMouseWheel (0, localPos, getMouseEventTime(), wheel);
|
||||
if (auto* peer = findPeerUnderMouse (localPos))
|
||||
peer->handleMouseWheel (getPointerType (wParam), localPos, getMouseEventTime(), wheel);
|
||||
}
|
||||
|
||||
bool doGestureEvent (LPARAM lParam)
|
||||
|
|
@ -2191,7 +2245,7 @@ private:
|
|||
{
|
||||
case 3: /*GID_ZOOM*/
|
||||
if (gi.dwFlags != 1 /*GF_BEGIN*/ && lastMagnifySize > 0)
|
||||
peer->handleMagnifyGesture (0, localPos, getMouseEventTime(),
|
||||
peer->handleMagnifyGesture (MouseInputSource::InputSourceType::touch, localPos, getMouseEventTime(),
|
||||
(float) (gi.ullArguments / (double) lastMagnifySize));
|
||||
|
||||
lastMagnifySize = gi.ullArguments;
|
||||
|
|
@ -2213,7 +2267,7 @@ private:
|
|||
LRESULT doTouchEvent (const int numInputs, HTOUCHINPUT eventHandle)
|
||||
{
|
||||
if ((styleFlags & windowIgnoresMouseClicks) != 0)
|
||||
if (HWNDComponentPeer* const parent = getOwnerOfWindow (GetParent (hwnd)))
|
||||
if (auto* parent = getOwnerOfWindow (GetParent (hwnd)))
|
||||
if (parent != this)
|
||||
return parent->doTouchEvent (numInputs, eventHandle);
|
||||
|
||||
|
|
@ -2235,7 +2289,9 @@ private:
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool handleTouchInput (const TOUCHINPUT& touch, const bool isDown, const bool isUp)
|
||||
bool handleTouchInput (const TOUCHINPUT& touch, const bool isDown, const bool isUp,
|
||||
const float touchPressure = MouseInputSource::invalidPressure,
|
||||
const float orientation = 0.0f)
|
||||
{
|
||||
bool isCancel = false;
|
||||
|
||||
|
|
@ -2243,7 +2299,7 @@ private:
|
|||
const int64 time = getMouseEventTime();
|
||||
const Point<float> pos (globalToLocal (Point<float> (touch.x / 100.0f,
|
||||
touch.y / 100.0f)));
|
||||
const float pressure = MouseInputSource::invalidPressure;
|
||||
const float pressure = touchPressure;
|
||||
ModifierKeys modsToSend (currentModifiers);
|
||||
|
||||
if (isDown)
|
||||
|
|
@ -2252,7 +2308,7 @@ private:
|
|||
modsToSend = currentModifiers;
|
||||
|
||||
// this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before.
|
||||
handleMouseEvent (touchIndex, pos, modsToSend.withoutMouseButtons(), pressure, time);
|
||||
handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, modsToSend.withoutMouseButtons(), pressure, orientation, time, PenDetails(), touchIndex);
|
||||
|
||||
if (! isValidPeer (this)) // (in case this component was deleted by the event)
|
||||
return false;
|
||||
|
|
@ -2276,14 +2332,14 @@ private:
|
|||
currentModifiers = currentModifiers.withoutMouseButtons();
|
||||
}
|
||||
|
||||
handleMouseEvent (touchIndex, pos, modsToSend, pressure, time);
|
||||
handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, modsToSend, pressure, orientation, time, PenDetails(), touchIndex);
|
||||
|
||||
if (! isValidPeer (this)) // (in case this component was deleted by the event)
|
||||
return false;
|
||||
|
||||
if (isUp || isCancel)
|
||||
{
|
||||
handleMouseEvent (touchIndex, Point<float> (-10.0f, -10.0f), currentModifiers, pressure, time);
|
||||
handleMouseEvent (MouseInputSource::InputSourceType::touch, Point<float> (-10.0f, -10.0f), currentModifiers, pressure, orientation, time, PenDetails(), touchIndex);
|
||||
|
||||
if (! isValidPeer (this))
|
||||
return false;
|
||||
|
|
@ -2293,6 +2349,47 @@ private:
|
|||
}
|
||||
|
||||
#ifdef WM_POINTERUPDATE
|
||||
bool handlePointerInput (WPARAM wParam, LPARAM lParam, const bool isDown, const bool isUp)
|
||||
{
|
||||
POINTER_INPUT_TYPE pointerType;
|
||||
if (! GetPointerType (GET_POINTERID_WPARAM (wParam), &pointerType))
|
||||
return false;
|
||||
|
||||
if (pointerType == 0x00000002) // PT_TOUCH
|
||||
{
|
||||
POINTER_TOUCH_INFO touchInfo;
|
||||
if (! GetPointerTouchInfo (GET_POINTERID_WPARAM (wParam), &touchInfo))
|
||||
return false;
|
||||
|
||||
const float pressure = touchInfo.touchMask & TOUCH_MASK_PRESSURE ? touchInfo.pressure : MouseInputSource::invalidPressure;
|
||||
const float orientation = touchInfo.touchMask & TOUCH_MASK_ORIENTATION ? degreesToRadians (static_cast<float> (touchInfo.orientation))
|
||||
: MouseInputSource::invalidOrientation;
|
||||
|
||||
if (! handleTouchInput (emulateTouchEventFromPointer (lParam, wParam),
|
||||
isDown, isUp, pressure, orientation))
|
||||
return false;
|
||||
}
|
||||
else if (pointerType == 0x00000003) // PT_PEN
|
||||
{
|
||||
POINTER_PEN_INFO penInfo;
|
||||
if (! GetPointerPenInfo (GET_POINTERID_WPARAM (wParam), &penInfo))
|
||||
return false;
|
||||
|
||||
const float pressure = (penInfo.penMask & PEN_MASK_PRESSURE) ? penInfo.pressure / 1024.0f : MouseInputSource::invalidPressure;
|
||||
|
||||
if (! handlePenInput (penInfo, globalToLocal (Point<float> (static_cast<float> (GET_X_LPARAM(lParam)),
|
||||
static_cast<float> (GET_Y_LPARAM(lParam)))),
|
||||
pressure, isDown, isUp))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TOUCHINPUT emulateTouchEventFromPointer (LPARAM lParam, WPARAM wParam)
|
||||
{
|
||||
TOUCHINPUT touchInput;
|
||||
|
|
@ -2303,6 +2400,58 @@ private:
|
|||
|
||||
return touchInput;
|
||||
}
|
||||
|
||||
bool handlePenInput (POINTER_PEN_INFO penInfo, Point<float> pos, const float pressure, bool isDown, bool isUp)
|
||||
{
|
||||
const int64 time = getMouseEventTime();
|
||||
ModifierKeys modsToSend (currentModifiers);
|
||||
PenDetails penDetails;
|
||||
|
||||
penDetails.rotation = (penInfo.penMask & PEN_MASK_ROTATION) ? degreesToRadians (static_cast<float> (penInfo.rotation)) : MouseInputSource::invalidRotation;
|
||||
penDetails.tiltX = (penInfo.penMask & PEN_MASK_TILT_X) ? penInfo.tiltX / 90.0f : MouseInputSource::invalidTiltX;
|
||||
penDetails.tiltY = (penInfo.penMask & PEN_MASK_TILT_Y) ? penInfo.tiltY / 90.0f : MouseInputSource::invalidTiltY;
|
||||
|
||||
auto pInfoFlags = penInfo.pointerInfo.pointerFlags;
|
||||
|
||||
if ((pInfoFlags & POINTER_FLAG_FIRSTBUTTON) != 0)
|
||||
currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier);
|
||||
else if ((pInfoFlags & POINTER_FLAG_SECONDBUTTON) != 0)
|
||||
currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::rightButtonModifier);
|
||||
|
||||
if (isDown)
|
||||
{
|
||||
modsToSend = currentModifiers;
|
||||
|
||||
// this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before.
|
||||
handleMouseEvent (MouseInputSource::InputSourceType::pen, pos, modsToSend.withoutMouseButtons(),
|
||||
pressure, MouseInputSource::invalidOrientation, time, penDetails);
|
||||
|
||||
if (! isValidPeer (this)) // (in case this component was deleted by the event)
|
||||
return false;
|
||||
}
|
||||
else if (isUp || ! (pInfoFlags & POINTER_FLAG_INCONTACT))
|
||||
{
|
||||
modsToSend = modsToSend.withoutMouseButtons();
|
||||
}
|
||||
|
||||
handleMouseEvent (MouseInputSource::InputSourceType::pen, pos, modsToSend, pressure,
|
||||
MouseInputSource::invalidOrientation, time, penDetails);
|
||||
|
||||
if (! isValidPeer (this)) // (in case this component was deleted by the event)
|
||||
return false;
|
||||
|
||||
if (isUp)
|
||||
{
|
||||
handleMouseEvent (MouseInputSource::InputSourceType::pen, { -10.0f, -10.0f }, currentModifiers,
|
||||
pressure, MouseInputSource::invalidOrientation, time, penDetails);
|
||||
|
||||
if (! isValidPeer (this))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -2583,7 +2732,8 @@ private:
|
|||
|
||||
if (contains (pos.roundToInt(), false))
|
||||
{
|
||||
doMouseEvent (pos, MouseInputSource::invalidPressure);
|
||||
if (! areOtherTouchSourcesActive())
|
||||
doMouseEvent (pos, MouseInputSource::invalidPressure);
|
||||
|
||||
if (! isValidPeer (this))
|
||||
return true;
|
||||
|
|
@ -2724,7 +2874,7 @@ private:
|
|||
public:
|
||||
static LRESULT CALLBACK windowProc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (HWNDComponentPeer* const peer = getOwnerOfWindow (h))
|
||||
if (auto* peer = getOwnerOfWindow (h))
|
||||
{
|
||||
jassert (isValidPeer (peer));
|
||||
return peer->peerWindowProc (h, message, wParam, lParam);
|
||||
|
|
@ -2794,13 +2944,25 @@ private:
|
|||
return 1;
|
||||
|
||||
//==============================================================================
|
||||
#ifdef WM_POINTERUPDATE
|
||||
case WM_POINTERUPDATE: handleTouchInput (emulateTouchEventFromPointer (lParam, wParam), false, false); return 0;
|
||||
case WM_POINTERDOWN: handleTouchInput (emulateTouchEventFromPointer (lParam, wParam), true, false); return 0;
|
||||
case WM_POINTERUP: handleTouchInput (emulateTouchEventFromPointer (lParam, wParam), false, true); return 0;
|
||||
#endif
|
||||
case WM_POINTERUPDATE:
|
||||
if (handlePointerInput (wParam, lParam, false, false))
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case WM_POINTERDOWN:
|
||||
if (handlePointerInput (wParam, lParam, true, false))
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case WM_POINTERUP:
|
||||
if (handlePointerInput (wParam, lParam, false, true))
|
||||
return 0;
|
||||
break;
|
||||
|
||||
//==============================================================================
|
||||
case WM_MOUSEMOVE: doMouseMove (getPointFromLParam (lParam), false); return 0;
|
||||
|
||||
case WM_POINTERLEAVE:
|
||||
case WM_MOUSELEAVE: doMouseExit(); return 0;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
|
|
@ -2811,11 +2973,15 @@ private:
|
|||
case WM_MBUTTONUP:
|
||||
case WM_RBUTTONUP: doMouseUp (getPointFromLParam (lParam), wParam); return 0;
|
||||
|
||||
case WM_POINTERWHEEL:
|
||||
case 0x020A: /* WM_MOUSEWHEEL */ doMouseWheel (wParam, true); return 0;
|
||||
|
||||
case WM_POINTERHWHEEL:
|
||||
case 0x020E: /* WM_MOUSEHWHEEL */ doMouseWheel (wParam, false); return 0;
|
||||
|
||||
case WM_CAPTURECHANGED: doCaptureChanged(); return 0;
|
||||
|
||||
case WM_NCPOINTERUPDATE:
|
||||
case WM_NCMOUSEMOVE:
|
||||
if (hasTitleBar())
|
||||
break;
|
||||
|
|
@ -2928,6 +3094,7 @@ private:
|
|||
|
||||
break;
|
||||
|
||||
case WM_POINTERACTIVATE:
|
||||
case WM_MOUSEACTIVATE:
|
||||
if (! component.getMouseClickGrabsKeyboardFocus())
|
||||
return MA_NOACTIVATE;
|
||||
|
|
@ -3054,6 +3221,7 @@ private:
|
|||
|
||||
break;
|
||||
|
||||
case WM_NCPOINTERDOWN:
|
||||
case WM_NCLBUTTONDOWN:
|
||||
handleLeftClickInNCArea (wParam);
|
||||
break;
|
||||
|
|
@ -3571,13 +3739,19 @@ bool MouseInputSource::SourceList::addSource()
|
|||
|
||||
if (numSources == 0 || canUseMultiTouch())
|
||||
{
|
||||
addSource (numSources, numSources == 0);
|
||||
addSource (numSources, numSources == 0 ? MouseInputSource::InputSourceType::mouse
|
||||
: MouseInputSource::InputSourceType::touch);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MouseInputSource::SourceList::canUseTouch()
|
||||
{
|
||||
return canUseMultiTouch();
|
||||
}
|
||||
|
||||
Point<float> MouseInputSource::getCurrentRawMousePosition()
|
||||
{
|
||||
POINT mousePos;
|
||||
|
|
|
|||
|
|
@ -1044,13 +1044,11 @@ public:
|
|||
|
||||
void restoreMouseIfHidden()
|
||||
{
|
||||
const Array<MouseInputSource>& mouseSources = Desktop::getInstance().getMouseSources();
|
||||
|
||||
for (MouseInputSource* mi = mouseSources.begin(), * const e = mouseSources.end(); mi != e; ++mi)
|
||||
for (auto& ms : Desktop::getInstance().getMouseSources())
|
||||
{
|
||||
if (mi->isUnboundedMouseMovementEnabled())
|
||||
if (ms.isUnboundedMouseMovementEnabled())
|
||||
{
|
||||
mi->enableUnboundedMouseMovement (false);
|
||||
ms.enableUnboundedMouseMovement (false);
|
||||
|
||||
const double pos = sliderBeingDragged == 2 ? getMaxValue()
|
||||
: (sliderBeingDragged == 1 ? getMinValue()
|
||||
|
|
@ -1059,7 +1057,7 @@ public:
|
|||
|
||||
if (isRotary())
|
||||
{
|
||||
mousePos = mi->getLastMouseDownPosition();
|
||||
mousePos = ms.getLastMouseDownPosition();
|
||||
|
||||
const float delta = (float) (pixelsForFullDragExtent * (owner.valueToProportionOfLength (valueOnMouseDown)
|
||||
- owner.valueToProportionOfLength (pos)));
|
||||
|
|
@ -1080,7 +1078,7 @@ public:
|
|||
isVertical() ? pixelPos : (owner.getHeight() / 2.0f)));
|
||||
}
|
||||
|
||||
mi->setScreenPosition (mousePos);
|
||||
ms.setScreenPosition (mousePos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,21 +85,22 @@ bool ComponentPeer::isKioskMode() const
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
void ComponentPeer::handleMouseEvent (int touchIndex, Point<float> pos, ModifierKeys newMods, float newPressure, int64 time)
|
||||
void ComponentPeer::handleMouseEvent (MouseInputSource::InputSourceType type, Point<float> pos, ModifierKeys newMods,
|
||||
float newPressure, float newOrientation, int64 time, PenDetails pen, int touchIndex)
|
||||
{
|
||||
if (MouseInputSource* mouse = Desktop::getInstance().mouseSources->getOrCreateMouseInputSource (touchIndex))
|
||||
MouseInputSource (*mouse).handleEvent (*this, pos, time, newMods, newPressure);
|
||||
if (auto* mouse = Desktop::getInstance().mouseSources->getOrCreateMouseInputSource (type, touchIndex))
|
||||
MouseInputSource (*mouse).handleEvent (*this, pos, time, newMods, newPressure, newOrientation, pen);
|
||||
}
|
||||
|
||||
void ComponentPeer::handleMouseWheel (int touchIndex, Point<float> pos, int64 time, const MouseWheelDetails& wheel)
|
||||
void ComponentPeer::handleMouseWheel (MouseInputSource::InputSourceType type, Point<float> pos, int64 time, const MouseWheelDetails& wheel, int touchIndex)
|
||||
{
|
||||
if (MouseInputSource* mouse = Desktop::getInstance().mouseSources->getOrCreateMouseInputSource (touchIndex))
|
||||
if (auto* mouse = Desktop::getInstance().mouseSources->getOrCreateMouseInputSource (type, touchIndex))
|
||||
MouseInputSource (*mouse).handleWheel (*this, pos, time, wheel);
|
||||
}
|
||||
|
||||
void ComponentPeer::handleMagnifyGesture (int touchIndex, Point<float> pos, int64 time, float scaleFactor)
|
||||
void ComponentPeer::handleMagnifyGesture (MouseInputSource::InputSourceType type, Point<float> pos, int64 time, float scaleFactor, int touchIndex)
|
||||
{
|
||||
if (MouseInputSource* mouse = Desktop::getInstance().mouseSources->getOrCreateMouseInputSource (touchIndex))
|
||||
if (auto* mouse = Desktop::getInstance().mouseSources->getOrCreateMouseInputSource (type, touchIndex))
|
||||
MouseInputSource (*mouse).handleMagnifyGesture (*this, pos, time, scaleFactor);
|
||||
}
|
||||
|
||||
|
|
@ -113,7 +114,7 @@ void ComponentPeer::handlePaint (LowLevelGraphicsContext& contextToPaintTo)
|
|||
if (component.isTransformed())
|
||||
g.addTransform (component.getTransform());
|
||||
|
||||
const Rectangle<int> peerBounds (getBounds());
|
||||
auto peerBounds = getBounds();
|
||||
|
||||
if (peerBounds.getWidth() != component.getWidth() || peerBounds.getHeight() != component.getHeight())
|
||||
// Tweak the scaling so that the component's integer size exactly aligns with the peer's scaled size
|
||||
|
|
|
|||
|
|
@ -310,9 +310,14 @@ public:
|
|||
virtual void setAlpha (float newAlpha) = 0;
|
||||
|
||||
//==============================================================================
|
||||
void handleMouseEvent (int touchIndex, Point<float> positionWithinPeer, ModifierKeys newMods, float pressure, int64 time);
|
||||
void handleMouseWheel (int touchIndex, Point<float> positionWithinPeer, int64 time, const MouseWheelDetails&);
|
||||
void handleMagnifyGesture (int touchIndex, Point<float> positionWithinPeer, int64 time, float scaleFactor);
|
||||
void handleMouseEvent (MouseInputSource::InputSourceType type, Point<float> positionWithinPeer, ModifierKeys newMods, float pressure,
|
||||
float orientation, int64 time, PenDetails pen = {}, int touchIndex = 0);
|
||||
|
||||
void handleMouseWheel (MouseInputSource::InputSourceType type, Point<float> positionWithinPeer,
|
||||
int64 time, const MouseWheelDetails&, int touchIndex = 0);
|
||||
|
||||
void handleMagnifyGesture (MouseInputSource::InputSourceType type, Point<float> positionWithinPeer,
|
||||
int64 time, float scaleFactor, int touchIndex = 0);
|
||||
|
||||
void handleUserClosingWindow();
|
||||
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ void TooltipWindow::timerCallback()
|
|||
const MouseInputSource mouseSource (desktop.getMainMouseSource());
|
||||
const unsigned int now = Time::getApproximateMillisecondCounter();
|
||||
|
||||
Component* const newComp = mouseSource.isMouse() ? mouseSource.getComponentUnderMouse() : nullptr;
|
||||
Component* const newComp = ! mouseSource.isTouch() ? mouseSource.getComponentUnderMouse() : nullptr;
|
||||
const String newTip (getTipFor (newComp));
|
||||
const bool tipChanged = (newTip != lastTipUnderMouse || newComp != lastComponentUnderMouse);
|
||||
lastComponentUnderMouse = newComp;
|
||||
|
|
|
|||
|
|
@ -92,41 +92,44 @@ public:
|
|||
if (owner.isCurrentlyBlockedByAnotherModalComponent())
|
||||
{
|
||||
if (isLeft || isRight)
|
||||
if (Component* const current = Component::getCurrentlyModalComponent())
|
||||
if (auto* current = Component::getCurrentlyModalComponent())
|
||||
current->inputAttemptWhenModal();
|
||||
}
|
||||
else
|
||||
{
|
||||
ModifierKeys eventMods (ModifierKeys::getCurrentModifiersRealtime());
|
||||
auto eventMods = ModifierKeys::getCurrentModifiersRealtime();
|
||||
|
||||
if (([e modifierFlags] & NSEventModifierFlagCommand) != 0)
|
||||
eventMods = eventMods.withFlags (ModifierKeys::commandModifier);
|
||||
|
||||
const Time now (Time::getCurrentTime());
|
||||
auto now = Time::getCurrentTime();
|
||||
|
||||
MouseInputSource mouseSource = Desktop::getInstance().getMainMouseSource();
|
||||
const float pressure = (float) e.pressure;
|
||||
auto pressure = (float) e.pressure;
|
||||
|
||||
if (isLeft || isRight) // Only mouse up is sent by the OS, so simulate a down/up
|
||||
{
|
||||
setHighlighted (true);
|
||||
startTimer (150);
|
||||
|
||||
owner.mouseDown (MouseEvent (mouseSource, Point<float>(),
|
||||
owner.mouseDown (MouseEvent (mouseSource, {},
|
||||
eventMods.withFlags (isLeft ? ModifierKeys::leftButtonModifier
|
||||
: ModifierKeys::rightButtonModifier),
|
||||
pressure, &owner, &owner, now,
|
||||
Point<float>(), now, 1, false));
|
||||
pressure, MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation,
|
||||
MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY,
|
||||
&owner, &owner, now, {}, now, 1, false));
|
||||
|
||||
owner.mouseUp (MouseEvent (mouseSource, Point<float>(), eventMods.withoutMouseButtons(),
|
||||
pressure, &owner, &owner, now,
|
||||
Point<float>(), now, 1, false));
|
||||
owner.mouseUp (MouseEvent (mouseSource, {}, eventMods.withoutMouseButtons(), pressure,
|
||||
MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation,
|
||||
MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY,
|
||||
&owner, &owner, now, {}, now, 1, false));
|
||||
}
|
||||
else if (type == NSEventTypeMouseMoved)
|
||||
{
|
||||
owner.mouseMove (MouseEvent (mouseSource, Point<float>(), eventMods,
|
||||
pressure, &owner, &owner, now,
|
||||
Point<float>(), now, 1, false));
|
||||
owner.mouseMove (MouseEvent (mouseSource, {}, eventMods, pressure,
|
||||
MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation,
|
||||
MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY,
|
||||
&owner, &owner, now, {}, now, 1, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -195,7 +198,7 @@ private:
|
|||
private:
|
||||
static void handleEventDown (id self, SEL, NSEvent* e)
|
||||
{
|
||||
if (Pimpl* const owner = getOwner (self))
|
||||
if (auto* owner = getOwner (self))
|
||||
owner->handleStatusItemAction (e);
|
||||
}
|
||||
|
||||
|
|
@ -203,7 +206,7 @@ private:
|
|||
{
|
||||
NSRect bounds = [self bounds];
|
||||
|
||||
if (Pimpl* const owner = getOwner (self))
|
||||
if (auto* owner = getOwner (self))
|
||||
[owner->statusItem drawStatusBarBackgroundInRect: bounds
|
||||
withHighlight: owner->isHighlighted];
|
||||
|
||||
|
|
|
|||
|
|
@ -204,10 +204,11 @@ namespace ActiveXHelpers
|
|||
case WM_LBUTTONUP:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_RBUTTONUP:
|
||||
peer->handleMouseEvent (0, Point<int> (GET_X_LPARAM (lParam) + activeXRect.left - peerRect.left,
|
||||
GET_Y_LPARAM (lParam) + activeXRect.top - peerRect.top).toFloat(),
|
||||
peer->handleMouseEvent (MouseInputSource::InputSourceType::mouse,
|
||||
{ (float) (GET_X_LPARAM (lParam) + activeXRect.left - peerRect.left),
|
||||
(float) (GET_Y_LPARAM (lParam) + activeXRect.top - peerRect.top) },
|
||||
ModifierKeys::getCurrentModifiersRealtime(),
|
||||
MouseInputSource::invalidPressure,
|
||||
MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation,
|
||||
getMouseEventTime());
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ public:
|
|||
if (lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN
|
||||
|| lParam == WM_LBUTTONDBLCLK || lParam == WM_RBUTTONDBLCLK)
|
||||
{
|
||||
if (Component* const current = Component::getCurrentlyModalComponent())
|
||||
if (auto* current = Component::getCurrentlyModalComponent())
|
||||
current->inputAttemptWhenModal();
|
||||
}
|
||||
}
|
||||
|
|
@ -110,9 +110,10 @@ public:
|
|||
|
||||
const Time eventTime (getMouseEventTime());
|
||||
|
||||
const MouseEvent e (Desktop::getInstance().getMainMouseSource(),
|
||||
Point<float>(), eventMods, MouseInputSource::invalidPressure,
|
||||
&owner, &owner, eventTime, Point<float>(), eventTime, 1, false);
|
||||
const MouseEvent e (Desktop::getInstance().getMainMouseSource(), {}, eventMods,
|
||||
MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation,
|
||||
MouseInputSource::invalidRotation, MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY,
|
||||
&owner, &owner, eventTime, {}, eventTime, 1, false);
|
||||
|
||||
if (lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue