@@ -58,7 +58,7 @@ public: | |||||
trails.add (t); | trails.add (t); | ||||
} | } | ||||
t->pushPoint (e.position, e.mods); | |||||
t->pushPoint (e.position, e.mods, e.pressure); | |||||
repaint(); | repaint(); | ||||
} | } | ||||
@@ -74,22 +74,26 @@ public: | |||||
: source (ms), colour (getRandomBrightColour().withAlpha (0.6f)) | : source (ms), colour (getRandomBrightColour().withAlpha (0.6f)) | ||||
{} | {} | ||||
void pushPoint (Point<float> p, ModifierKeys newMods) | |||||
void pushPoint (Point<float> newPoint, ModifierKeys newMods, float pressure) | |||||
{ | { | ||||
currentPosition = p; | |||||
currentPosition = newPoint; | |||||
modifierKeys = newMods; | modifierKeys = newMods; | ||||
if (lastPoint.getDistanceFrom(p) > 5.0f) | |||||
if (lastPoint.getDistanceFrom (newPoint) > 5.0f) | |||||
{ | { | ||||
if (lastPoint != Point<float>()) | if (lastPoint != Point<float>()) | ||||
{ | { | ||||
path.quadraticTo (lastPoint, p); | |||||
lastPoint = Point<float>(); | |||||
} | |||||
else | |||||
{ | |||||
lastPoint = p; | |||||
Path newSegment; | |||||
newSegment.startNewSubPath (lastPoint); | |||||
newSegment.lineTo (newPoint); | |||||
float diameter = 20.0f * (pressure > 0 && pressure < 1.0f ? pressure : 1.0f); | |||||
PathStrokeType (diameter, PathStrokeType::curved, PathStrokeType::rounded).createStrokedPath (newSegment, newSegment); | |||||
path.addPath (newSegment); | |||||
} | } | ||||
lastPoint = newPoint; | |||||
} | } | ||||
} | } | ||||
@@ -107,7 +111,7 @@ public: | |||||
void drawTrail (Trail& trail, Graphics& g) | void drawTrail (Trail& trail, Graphics& g) | ||||
{ | { | ||||
g.setColour (trail.colour); | g.setColour (trail.colour); | ||||
g.strokePath (trail.path, PathStrokeType (20.0f, PathStrokeType::curved, PathStrokeType::rounded)); | |||||
g.fillPath (trail.path); | |||||
const float radius = 40.0f; | const float radius = 40.0f; | ||||
@@ -121,6 +125,11 @@ public: | |||||
String desc ("Mouse #"); | String desc ("Mouse #"); | ||||
desc << trail.source.getIndex(); | desc << trail.source.getIndex(); | ||||
float pressure = trail.source.getCurrentPressure(); | |||||
if (pressure > 0.0f && pressure < 1.0f) | |||||
desc << " (pressure: " << (int) (pressure * 100.0f) << "%)"; | |||||
if (trail.modifierKeys.isCommandDown()) desc << " (CMD)"; | if (trail.modifierKeys.isCommandDown()) desc << " (CMD)"; | ||||
if (trail.modifierKeys.isShiftDown()) desc << " (SHIFT)"; | if (trail.modifierKeys.isShiftDown()) desc << " (SHIFT)"; | ||||
if (trail.modifierKeys.isCtrlDown()) desc << " (CTRL)"; | if (trail.modifierKeys.isCtrlDown()) desc << " (CTRL)"; | ||||
@@ -51,7 +51,8 @@ public: | |||||
if (Component* const comp = Desktop::getInstance().findComponentAt (screenPos.roundToInt())) | if (Component* const comp = Desktop::getInstance().findComponentAt (screenPos.roundToInt())) | ||||
if (ComponentPeer* const peer = comp->getPeer()) | if (ComponentPeer* const peer = comp->getPeer()) | ||||
if (! peer->isFocused()) | if (! peer->isFocused()) | ||||
peer->handleMouseEvent (0, peer->globalToLocal (screenPos), mods, Time::currentTimeMillis()); | |||||
peer->handleMouseEvent (0, peer->globalToLocal (screenPos), mods, | |||||
MouseInputSource::invalidPressure, Time::currentTimeMillis()); | |||||
} | } | ||||
} | } | ||||
@@ -2384,7 +2384,7 @@ void Component::internalMouseEnter (MouseInputSource source, Point<float> relati | |||||
BailOutChecker checker (this); | BailOutChecker checker (this); | ||||
const MouseEvent me (source, relativePos, source.getCurrentModifiers(), | |||||
const MouseEvent me (source, relativePos, source.getCurrentModifiers(), MouseInputSource::invalidPressure, | |||||
this, this, time, relativePos, time, 0, false); | this, this, time, relativePos, time, 0, false); | ||||
mouseEnter (me); | mouseEnter (me); | ||||
@@ -2403,7 +2403,7 @@ void Component::internalMouseExit (MouseInputSource source, Point<float> relativ | |||||
BailOutChecker checker (this); | BailOutChecker checker (this); | ||||
const MouseEvent me (source, relativePos, source.getCurrentModifiers(), | |||||
const MouseEvent me (source, relativePos, source.getCurrentModifiers(), MouseInputSource::invalidPressure, | |||||
this, this, time, relativePos, time, 0, false); | this, this, time, relativePos, time, 0, false); | ||||
mouseExit (me); | mouseExit (me); | ||||
@@ -2416,7 +2416,7 @@ void Component::internalMouseExit (MouseInputSource source, Point<float> relativ | |||||
MouseListenerList::sendMouseEvent (*this, checker, &MouseListener::mouseExit, me); | MouseListenerList::sendMouseEvent (*this, checker, &MouseListener::mouseExit, me); | ||||
} | } | ||||
void Component::internalMouseDown (MouseInputSource source, Point<float> relativePos, Time time) | |||||
void Component::internalMouseDown (MouseInputSource source, Point<float> relativePos, Time time, float pressure) | |||||
{ | { | ||||
Desktop& desktop = Desktop::getInstance(); | Desktop& desktop = Desktop::getInstance(); | ||||
BailOutChecker checker (this); | BailOutChecker checker (this); | ||||
@@ -2435,7 +2435,7 @@ void Component::internalMouseDown (MouseInputSource source, Point<float> relativ | |||||
{ | { | ||||
// allow blocked mouse-events to go to global listeners.. | // allow blocked mouse-events to go to global listeners.. | ||||
const MouseEvent me (source, relativePos, source.getCurrentModifiers(), | const MouseEvent me (source, relativePos, source.getCurrentModifiers(), | ||||
this, this, time, relativePos, time, | |||||
pressure, this, this, time, relativePos, time, | |||||
source.getNumberOfMultipleClicks(), false); | source.getNumberOfMultipleClicks(), false); | ||||
desktop.getMouseListeners().callChecked (checker, &MouseListener::mouseDown, me); | desktop.getMouseListeners().callChecked (checker, &MouseListener::mouseDown, me); | ||||
@@ -2468,7 +2468,7 @@ void Component::internalMouseDown (MouseInputSource source, Point<float> relativ | |||||
repaint(); | repaint(); | ||||
const MouseEvent me (source, relativePos, source.getCurrentModifiers(), | const MouseEvent me (source, relativePos, source.getCurrentModifiers(), | ||||
this, this, time, relativePos, time, | |||||
pressure, this, this, time, relativePos, time, | |||||
source.getNumberOfMultipleClicks(), false); | source.getNumberOfMultipleClicks(), false); | ||||
mouseDown (me); | mouseDown (me); | ||||
@@ -2492,7 +2492,7 @@ void Component::internalMouseUp (MouseInputSource source, Point<float> relativeP | |||||
repaint(); | repaint(); | ||||
const MouseEvent me (source, relativePos, | const MouseEvent me (source, relativePos, | ||||
oldModifiers, this, this, time, | |||||
oldModifiers, MouseInputSource::invalidPressure, this, this, time, | |||||
getLocalPoint (nullptr, source.getLastMouseDownPosition()), | getLocalPoint (nullptr, source.getLastMouseDownPosition()), | ||||
source.getLastMouseDownTime(), | source.getLastMouseDownTime(), | ||||
source.getNumberOfMultipleClicks(), | source.getNumberOfMultipleClicks(), | ||||
@@ -2523,14 +2523,14 @@ void Component::internalMouseUp (MouseInputSource source, Point<float> relativeP | |||||
} | } | ||||
} | } | ||||
void Component::internalMouseDrag (MouseInputSource source, Point<float> relativePos, Time time) | |||||
void Component::internalMouseDrag (MouseInputSource source, Point<float> relativePos, Time time, float pressure) | |||||
{ | { | ||||
if (! isCurrentlyBlockedByAnotherModalComponent()) | if (! isCurrentlyBlockedByAnotherModalComponent()) | ||||
{ | { | ||||
BailOutChecker checker (this); | BailOutChecker checker (this); | ||||
const MouseEvent me (source, relativePos, | |||||
source.getCurrentModifiers(), this, this, time, | |||||
const MouseEvent me (source, relativePos, source.getCurrentModifiers(), | |||||
pressure, this, this, time, | |||||
getLocalPoint (nullptr, source.getLastMouseDownPosition()), | getLocalPoint (nullptr, source.getLastMouseDownPosition()), | ||||
source.getLastMouseDownTime(), | source.getLastMouseDownTime(), | ||||
source.getNumberOfMultipleClicks(), | source.getNumberOfMultipleClicks(), | ||||
@@ -2559,7 +2559,7 @@ void Component::internalMouseMove (MouseInputSource source, Point<float> relativ | |||||
{ | { | ||||
BailOutChecker checker (this); | BailOutChecker checker (this); | ||||
const MouseEvent me (source, relativePos, source.getCurrentModifiers(), | |||||
const MouseEvent me (source, relativePos, source.getCurrentModifiers(), MouseInputSource::invalidPressure, | |||||
this, this, time, relativePos, time, 0, false); | this, this, time, relativePos, time, 0, false); | ||||
mouseMove (me); | mouseMove (me); | ||||
@@ -2578,7 +2578,7 @@ void Component::internalMouseWheel (MouseInputSource source, Point<float> relati | |||||
Desktop& desktop = Desktop::getInstance(); | Desktop& desktop = Desktop::getInstance(); | ||||
BailOutChecker checker (this); | BailOutChecker checker (this); | ||||
const MouseEvent me (source, relativePos, source.getCurrentModifiers(), | |||||
const MouseEvent me (source, relativePos, source.getCurrentModifiers(), MouseInputSource::invalidPressure, | |||||
this, this, time, relativePos, time, 0, false); | this, this, time, relativePos, time, 0, false); | ||||
if (isCurrentlyBlockedByAnotherModalComponent()) | if (isCurrentlyBlockedByAnotherModalComponent()) | ||||
@@ -2605,7 +2605,7 @@ void Component::internalMagnifyGesture (MouseInputSource source, Point<float> re | |||||
{ | { | ||||
if (! isCurrentlyBlockedByAnotherModalComponent()) | if (! isCurrentlyBlockedByAnotherModalComponent()) | ||||
{ | { | ||||
const MouseEvent me (source, relativePos, source.getCurrentModifiers(), | |||||
const MouseEvent me (source, relativePos, source.getCurrentModifiers(), MouseInputSource::invalidPressure, | |||||
this, this, time, relativePos, time, 0, false); | this, this, time, relativePos, time, 0, false); | ||||
mouseMagnify (me, amount); | mouseMagnify (me, amount); | ||||
@@ -2300,9 +2300,9 @@ private: | |||||
//============================================================================== | //============================================================================== | ||||
void internalMouseEnter (MouseInputSource, Point<float>, Time); | void internalMouseEnter (MouseInputSource, Point<float>, Time); | ||||
void internalMouseExit (MouseInputSource, Point<float>, Time); | void internalMouseExit (MouseInputSource, Point<float>, Time); | ||||
void internalMouseDown (MouseInputSource, Point<float>, Time); | |||||
void internalMouseDown (MouseInputSource, Point<float>, Time, float); | |||||
void internalMouseUp (MouseInputSource, Point<float>, Time, const ModifierKeys oldModifiers); | void internalMouseUp (MouseInputSource, Point<float>, Time, const ModifierKeys oldModifiers); | ||||
void internalMouseDrag (MouseInputSource, Point<float>, Time); | |||||
void internalMouseDrag (MouseInputSource, Point<float>, Time, float); | |||||
void internalMouseMove (MouseInputSource, Point<float>, Time); | void internalMouseMove (MouseInputSource, Point<float>, Time); | ||||
void internalMouseWheel (MouseInputSource, Point<float>, Time, const MouseWheelDetails&); | void internalMouseWheel (MouseInputSource, Point<float>, Time, const MouseWheelDetails&); | ||||
void internalMagnifyGesture (MouseInputSource, Point<float>, Time, float); | void internalMagnifyGesture (MouseInputSource, Point<float>, Time, float); | ||||
@@ -246,7 +246,7 @@ void Desktop::sendMouseMove() | |||||
const Time now (Time::getCurrentTime()); | const Time now (Time::getCurrentTime()); | ||||
const MouseEvent me (getMainMouseSource(), pos, ModifierKeys::getCurrentModifiers(), | const MouseEvent me (getMainMouseSource(), pos, ModifierKeys::getCurrentModifiers(), | ||||
target, target, now, pos, now, 0, false); | |||||
MouseInputSource::invalidPressure, target, target, now, pos, now, 0, false); | |||||
if (me.mods.isAnyMouseButtonDown()) | if (me.mods.isAnyMouseButtonDown()) | ||||
mouseListeners.callChecked (checker, &MouseListener::mouseDrag, me); | mouseListeners.callChecked (checker, &MouseListener::mouseDrag, me); | ||||
@@ -25,6 +25,7 @@ | |||||
MouseEvent::MouseEvent (MouseInputSource inputSource, | MouseEvent::MouseEvent (MouseInputSource inputSource, | ||||
Point<float> pos, | Point<float> pos, | ||||
ModifierKeys modKeys, | ModifierKeys modKeys, | ||||
float force, | |||||
Component* const eventComp, | Component* const eventComp, | ||||
Component* const originator, | Component* const originator, | ||||
Time time, | Time time, | ||||
@@ -36,6 +37,7 @@ MouseEvent::MouseEvent (MouseInputSource inputSource, | |||||
x (roundToInt (pos.x)), | x (roundToInt (pos.x)), | ||||
y (roundToInt (pos.y)), | y (roundToInt (pos.y)), | ||||
mods (modKeys), | mods (modKeys), | ||||
pressure (force), | |||||
eventComponent (eventComp), | eventComponent (eventComp), | ||||
originalComponent (originator), | originalComponent (originator), | ||||
eventTime (time), | eventTime (time), | ||||
@@ -57,22 +59,22 @@ MouseEvent MouseEvent::getEventRelativeTo (Component* const otherComponent) cons | |||||
jassert (otherComponent != nullptr); | jassert (otherComponent != nullptr); | ||||
return MouseEvent (source, otherComponent->getLocalPoint (eventComponent, position), | return MouseEvent (source, otherComponent->getLocalPoint (eventComponent, position), | ||||
mods, otherComponent, originalComponent, eventTime, | |||||
mods, pressure, otherComponent, originalComponent, eventTime, | |||||
otherComponent->getLocalPoint (eventComponent, mouseDownPos), | otherComponent->getLocalPoint (eventComponent, mouseDownPos), | ||||
mouseDownTime, numberOfClicks, wasMovedSinceMouseDown != 0); | mouseDownTime, numberOfClicks, wasMovedSinceMouseDown != 0); | ||||
} | } | ||||
MouseEvent MouseEvent::withNewPosition (Point<float> newPosition) const noexcept | MouseEvent MouseEvent::withNewPosition (Point<float> newPosition) const noexcept | ||||
{ | { | ||||
return MouseEvent (source, newPosition, mods, eventComponent, originalComponent, | |||||
eventTime, mouseDownPos, mouseDownTime, | |||||
return MouseEvent (source, newPosition, mods, pressure, eventComponent, | |||||
originalComponent, eventTime, mouseDownPos, mouseDownTime, | |||||
numberOfClicks, wasMovedSinceMouseDown != 0); | numberOfClicks, wasMovedSinceMouseDown != 0); | ||||
} | } | ||||
MouseEvent MouseEvent::withNewPosition (Point<int> newPosition) const noexcept | MouseEvent MouseEvent::withNewPosition (Point<int> newPosition) const noexcept | ||||
{ | { | ||||
return MouseEvent (source, newPosition.toFloat(), mods, eventComponent, originalComponent, | |||||
eventTime, mouseDownPos, mouseDownTime, | |||||
return MouseEvent (source, newPosition.toFloat(), mods, pressure, eventComponent, | |||||
originalComponent, eventTime, mouseDownPos, mouseDownTime, | |||||
numberOfClicks, wasMovedSinceMouseDown != 0); | numberOfClicks, wasMovedSinceMouseDown != 0); | ||||
} | } | ||||
@@ -112,6 +114,8 @@ int MouseEvent::getScreenY() const { return getScre | |||||
int MouseEvent::getMouseDownScreenX() const { return getMouseDownScreenPosition().x; } | int MouseEvent::getMouseDownScreenX() const { return getMouseDownScreenPosition().x; } | ||||
int MouseEvent::getMouseDownScreenY() const { return getMouseDownScreenPosition().y; } | int MouseEvent::getMouseDownScreenY() const { return getMouseDownScreenPosition().y; } | ||||
bool MouseEvent::isPressureValid() const noexcept { return pressure > 0.0f && pressure < 1.0f; } | |||||
//============================================================================== | //============================================================================== | ||||
static int doubleClickTimeOutMs = 400; | static int doubleClickTimeOutMs = 400; | ||||
@@ -44,6 +44,9 @@ public: | |||||
@param source the source that's invoking the event | @param source the source that's invoking the event | ||||
@param position the position of the mouse, relative to the component that is passed-in | @param position the position of the mouse, relative to the component that is passed-in | ||||
@param modifiers the key modifiers at the time of the event | @param modifiers the key modifiers at the time of the event | ||||
@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 eventComponent the component that the mouse event applies to | @param eventComponent the component that the mouse event applies to | ||||
@param originator the component that originally received the event | @param originator the component that originally received the event | ||||
@param eventTime the time the event happened | @param eventTime the time the event happened | ||||
@@ -59,6 +62,7 @@ public: | |||||
MouseEvent (MouseInputSource source, | MouseEvent (MouseInputSource source, | ||||
Point<float> position, | Point<float> position, | ||||
ModifierKeys modifiers, | ModifierKeys modifiers, | ||||
float pressure, | |||||
Component* eventComponent, | Component* eventComponent, | ||||
Component* originator, | Component* originator, | ||||
Time eventTime, | Time eventTime, | ||||
@@ -109,6 +113,13 @@ public: | |||||
*/ | */ | ||||
const ModifierKeys mods; | const ModifierKeys mods; | ||||
/** The pressure of the touch or stylus for this event. | |||||
The range is 0 (soft) to 1 (hard). | |||||
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; | |||||
/** The component that this event applies to. | /** The component that this event applies to. | ||||
This is usually the component that the mouse was over at the time, but for mouse-drag | This is usually the component that the mouse was over at the time, but for mouse-drag | ||||
@@ -224,6 +235,9 @@ public: | |||||
*/ | */ | ||||
int getLengthOfMousePress() const noexcept; | int getLengthOfMousePress() const noexcept; | ||||
/** Returns true if the pressure value for this event is meaningful. */ | |||||
bool isPressureValid() const noexcept; | |||||
//============================================================================== | //============================================================================== | ||||
/** The position of the mouse when the event occurred. | /** The position of the mouse when the event occurred. | ||||
@@ -27,7 +27,7 @@ class MouseInputSourceInternal : private AsyncUpdater | |||||
public: | public: | ||||
//============================================================================== | //============================================================================== | ||||
MouseInputSourceInternal (const int i, const bool isMouse) | MouseInputSourceInternal (const int i, const bool isMouse) | ||||
: index (i), isMouseDevice (isMouse), | |||||
: index (i), isMouseDevice (isMouse), pressure (0.0f), | |||||
isUnboundedMouseModeOn (false), isCursorVisibleUntilOffscreen (false), | isUnboundedMouseModeOn (false), isCursorVisibleUntilOffscreen (false), | ||||
lastPeer (nullptr), currentCursorHandle (nullptr), | lastPeer (nullptr), currentCursorHandle (nullptr), | ||||
mouseEventCounter (0), mouseMovedSignificantlySincePressed (false) | mouseEventCounter (0), mouseMovedSignificantlySincePressed (false) | ||||
@@ -40,17 +40,17 @@ public: | |||||
return buttonState.isAnyMouseButtonDown(); | return buttonState.isAnyMouseButtonDown(); | ||||
} | } | ||||
Component* getComponentUnderMouse() const | |||||
Component* getComponentUnderMouse() const noexcept | |||||
{ | { | ||||
return componentUnderMouse.get(); | return componentUnderMouse.get(); | ||||
} | } | ||||
ModifierKeys getCurrentModifiers() const | |||||
ModifierKeys getCurrentModifiers() const noexcept | |||||
{ | { | ||||
return ModifierKeys::getCurrentModifiers().withoutMouseButtons().withFlags (buttonState.getRawFlags()); | return ModifierKeys::getCurrentModifiers().withoutMouseButtons().withFlags (buttonState.getRawFlags()); | ||||
} | } | ||||
ComponentPeer* getPeer() | |||||
ComponentPeer* getPeer() noexcept | |||||
{ | { | ||||
if (! ComponentPeer::isValidPeer (lastPeer)) | if (! ComponentPeer::isValidPeer (lastPeer)) | ||||
lastPeer = nullptr; | lastPeer = nullptr; | ||||
@@ -102,6 +102,8 @@ public: | |||||
MouseInputSource::setRawMousePosition (ScalingHelpers::scaledScreenPosToUnscaled (p)); | MouseInputSource::setRawMousePosition (ScalingHelpers::scaledScreenPosToUnscaled (p)); | ||||
} | } | ||||
bool isPressureValid() const noexcept { return pressure > 0.0f && pressure < 1.0f; } | |||||
//============================================================================== | //============================================================================== | ||||
#if JUCE_DUMP_MOUSE_EVENTS | #if JUCE_DUMP_MOUSE_EVENTS | ||||
#define JUCE_MOUSE_EVENT_DBG(desc) DBG ("Mouse " << desc << " #" << index \ | #define JUCE_MOUSE_EVENT_DBG(desc) DBG ("Mouse " << desc << " #" << index \ | ||||
@@ -132,13 +134,13 @@ public: | |||||
void sendMouseDown (Component& comp, Point<float> screenPos, Time time) | void sendMouseDown (Component& comp, Point<float> screenPos, Time time) | ||||
{ | { | ||||
JUCE_MOUSE_EVENT_DBG ("down") | JUCE_MOUSE_EVENT_DBG ("down") | ||||
comp.internalMouseDown (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time); | |||||
comp.internalMouseDown (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time, pressure); | |||||
} | } | ||||
void sendMouseDrag (Component& comp, Point<float> screenPos, Time time) | void sendMouseDrag (Component& comp, Point<float> screenPos, Time time) | ||||
{ | { | ||||
JUCE_MOUSE_EVENT_DBG ("drag") | JUCE_MOUSE_EVENT_DBG ("drag") | ||||
comp.internalMouseDrag (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time); | |||||
comp.internalMouseDrag (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time, pressure); | |||||
} | } | ||||
void sendMouseUp (Component& comp, Point<float> screenPos, Time time, const ModifierKeys oldMods) | void sendMouseUp (Component& comp, Point<float> screenPos, Time time, const ModifierKeys oldMods) | ||||
@@ -287,15 +289,18 @@ public: | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
void handleEvent (ComponentPeer& newPeer, Point<float> positionWithinPeer, Time time, const ModifierKeys newMods) | |||||
void handleEvent (ComponentPeer& newPeer, Point<float> positionWithinPeer, Time time, | |||||
const ModifierKeys newMods, float newPressure) | |||||
{ | { | ||||
lastTime = time; | lastTime = time; | ||||
const bool pressureChanged = (pressure != newPressure); | |||||
pressure = newPressure; | |||||
++mouseEventCounter; | ++mouseEventCounter; | ||||
const Point<float> screenPos (newPeer.localToGlobal (positionWithinPeer)); | const Point<float> screenPos (newPeer.localToGlobal (positionWithinPeer)); | ||||
if (isDragging() && newMods.isAnyMouseButtonDown()) | if (isDragging() && newMods.isAnyMouseButtonDown()) | ||||
{ | { | ||||
setScreenPos (screenPos, time, false); | |||||
setScreenPos (screenPos, time, pressureChanged); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
@@ -307,8 +312,9 @@ public: | |||||
return; // some modal events have been dispatched, so the current event is now out-of-date | return; // some modal events have been dispatched, so the current event is now out-of-date | ||||
peer = getPeer(); | peer = getPeer(); | ||||
if (peer != nullptr) | if (peer != nullptr) | ||||
setScreenPos (screenPos, time, false); | |||||
setScreenPos (screenPos, time, pressureChanged); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -470,6 +476,7 @@ public: | |||||
const bool isMouseDevice; | const bool isMouseDevice; | ||||
Point<float> lastScreenPos, unboundedMouseOffset; // NB: these are unscaled coords | Point<float> lastScreenPos, unboundedMouseOffset; // NB: these are unscaled coords | ||||
ModifierKeys buttonState; | ModifierKeys buttonState; | ||||
float pressure; | |||||
bool isUnboundedMouseModeOn, isCursorVisibleUntilOffscreen; | bool isUnboundedMouseModeOn, isCursorVisibleUntilOffscreen; | ||||
@@ -542,14 +549,16 @@ MouseInputSource& MouseInputSource::operator= (const MouseInputSource& other) no | |||||
return *this; | return *this; | ||||
} | } | ||||
bool MouseInputSource::isMouse() const { return pimpl->isMouseDevice; } | |||||
bool MouseInputSource::isTouch() const { return ! isMouse(); } | |||||
bool MouseInputSource::canHover() const { return isMouse(); } | |||||
bool MouseInputSource::hasMouseWheel() const { return isMouse(); } | |||||
int MouseInputSource::getIndex() const { return pimpl->index; } | |||||
bool MouseInputSource::isDragging() const { return pimpl->isDragging(); } | |||||
Point<float> MouseInputSource::getScreenPosition() const { return pimpl->getScreenPosition(); } | |||||
ModifierKeys MouseInputSource::getCurrentModifiers() const { return pimpl->getCurrentModifiers(); } | |||||
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(); } | Component* MouseInputSource::getComponentUnderMouse() const { return pimpl->getComponentUnderMouse(); } | ||||
void MouseInputSource::triggerFakeMove() const { pimpl->triggerFakeMove(); } | void MouseInputSource::triggerFakeMove() const { pimpl->triggerFakeMove(); } | ||||
int MouseInputSource::getNumberOfMultipleClicks() const noexcept { return pimpl->getNumberOfMultipleClicks(); } | int MouseInputSource::getNumberOfMultipleClicks() const noexcept { return pimpl->getNumberOfMultipleClicks(); } | ||||
@@ -567,9 +576,9 @@ void MouseInputSource::revealCursor() { pimpl | |||||
void MouseInputSource::forceMouseCursorUpdate() { pimpl->revealCursor (true); } | void MouseInputSource::forceMouseCursorUpdate() { pimpl->revealCursor (true); } | ||||
void MouseInputSource::setScreenPosition (Point<float> p) { pimpl->setScreenPosition (p); } | void MouseInputSource::setScreenPosition (Point<float> p) { pimpl->setScreenPosition (p); } | ||||
void MouseInputSource::handleEvent (ComponentPeer& peer, Point<float> pos, int64 time, ModifierKeys mods) | |||||
void MouseInputSource::handleEvent (ComponentPeer& peer, Point<float> pos, int64 time, ModifierKeys mods, float pressure) | |||||
{ | { | ||||
pimpl->handleEvent (peer, pos, Time (time), mods.withOnlyMouseButtons()); | |||||
pimpl->handleEvent (peer, pos, Time (time), mods.withOnlyMouseButtons(), pressure); | |||||
} | } | ||||
void MouseInputSource::handleWheel (ComponentPeer& peer, Point<float> pos, int64 time, const MouseWheelDetails& wheel) | void MouseInputSource::handleWheel (ComponentPeer& peer, Point<float> pos, int64 time, const MouseWheelDetails& wheel) | ||||
@@ -582,6 +591,8 @@ void MouseInputSource::handleMagnifyGesture (ComponentPeer& peer, Point<float> p | |||||
pimpl->handleMagnifyGesture (peer, pos, Time (time), scaleFactor); | pimpl->handleMagnifyGesture (peer, pos, Time (time), scaleFactor); | ||||
} | } | ||||
const float MouseInputSource::invalidPressure = 0.0f; | |||||
//============================================================================== | //============================================================================== | ||||
struct MouseInputSource::SourceList : public Timer | struct MouseInputSource::SourceList : public Timer | ||||
{ | { | ||||
@@ -60,18 +60,18 @@ public: | |||||
//============================================================================== | //============================================================================== | ||||
/** Returns true if this object represents a normal desk-based mouse device. */ | /** Returns true if this object represents a normal desk-based mouse device. */ | ||||
bool isMouse() const; | |||||
bool isMouse() const noexcept; | |||||
/** Returns true if this object represents a source of touch events - i.e. a finger or stylus. */ | /** Returns true if this object represents a source of touch events - i.e. a finger or stylus. */ | ||||
bool isTouch() const; | |||||
bool isTouch() const noexcept; | |||||
/** Returns true if this source has an on-screen pointer that can hover over | /** Returns true if this source has an on-screen pointer that can hover over | ||||
items without clicking them. | items without clicking them. | ||||
*/ | */ | ||||
bool canHover() const; | |||||
bool canHover() const noexcept; | |||||
/** Returns true if this source may have a scroll wheel. */ | /** Returns true if this source may have a scroll wheel. */ | ||||
bool hasMouseWheel() const; | |||||
bool hasMouseWheel() const noexcept; | |||||
/** Returns this source's index in the global list of possible sources. | /** Returns this source's index in the global list of possible sources. | ||||
If the system only has a single mouse, there will only be a single MouseInputSource | If the system only has a single mouse, there will only be a single MouseInputSource | ||||
@@ -82,18 +82,28 @@ public: | |||||
number 0, and then if a second touch happens while the first is still down, it | number 0, and then if a second touch happens while the first is still down, it | ||||
will have index 1, etc. | will have index 1, etc. | ||||
*/ | */ | ||||
int getIndex() const; | |||||
int getIndex() const noexcept; | |||||
/** Returns true if this device is currently being pressed. */ | /** Returns true if this device is currently being pressed. */ | ||||
bool isDragging() const; | |||||
bool isDragging() const noexcept; | |||||
/** Returns the last-known screen position of this source. */ | /** Returns the last-known screen position of this source. */ | ||||
Point<float> getScreenPosition() const; | |||||
Point<float> getScreenPosition() const noexcept; | |||||
/** Returns a set of modifiers that indicate which buttons are currently | /** Returns a set of modifiers that indicate which buttons are currently | ||||
held down on this device. | held down on this device. | ||||
*/ | */ | ||||
ModifierKeys getCurrentModifiers() const; | |||||
ModifierKeys getCurrentModifiers() const noexcept; | |||||
/** Returns the device's current touch or pen pressure. | |||||
The range is 0 (soft) to 1 (hard). | |||||
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 getCurrentPressure() const noexcept; | |||||
/** Returns true if the current pressure value is meaningful. */ | |||||
bool isPressureValid() const noexcept; | |||||
/** Returns the component that was last known to be under this pointer. */ | /** Returns the component that was last known to be under this pointer. */ | ||||
Component* getComponentUnderMouse() const; | Component* getComponentUnderMouse() const; | ||||
@@ -164,6 +174,11 @@ public: | |||||
/** Attempts to set this mouse pointer's screen position. */ | /** Attempts to set this mouse pointer's screen position. */ | ||||
void setScreenPosition (Point<float> newPosition); | void setScreenPosition (Point<float> newPosition); | ||||
/** A default value for pressure, which is used when a device doesn't support it, or for | |||||
mouse-moves, mouse-ups, etc. | |||||
*/ | |||||
static const float invalidPressure; | |||||
private: | private: | ||||
//============================================================================== | //============================================================================== | ||||
friend class ComponentPeer; | friend class ComponentPeer; | ||||
@@ -174,7 +189,7 @@ private: | |||||
struct SourceList; | struct SourceList; | ||||
explicit MouseInputSource (MouseInputSourceInternal*) noexcept; | explicit MouseInputSource (MouseInputSourceInternal*) noexcept; | ||||
void handleEvent (ComponentPeer&, Point<float>, int64 time, ModifierKeys); | |||||
void handleEvent (ComponentPeer&, Point<float>, int64 time, ModifierKeys, float); | |||||
void handleWheel (ComponentPeer&, Point<float>, int64 time, const MouseWheelDetails&); | void handleWheel (ComponentPeer&, Point<float>, int64 time, const MouseWheelDetails&); | ||||
void handleMagnifyGesture (ComponentPeer&, Point<float>, int64 time, float scaleFactor); | void handleMagnifyGesture (ComponentPeer&, Point<float>, int64 time, float scaleFactor); | ||||
@@ -332,7 +332,7 @@ public: | |||||
lastMousePos = pos; | lastMousePos = pos; | ||||
// this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before. | // 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(), time); | |||||
handleMouseEvent (index, pos, currentModifiers.withoutMouseButtons(), MouseInputSource::invalidPressure, time); | |||||
if (isValidPeer (this)) | if (isValidPeer (this)) | ||||
handleMouseDragCallback (index, sysPos, time); | handleMouseDragCallback (index, sysPos, time); | ||||
@@ -346,8 +346,8 @@ public: | |||||
jassert (index < 64); | jassert (index < 64); | ||||
touchesDown = (touchesDown | (1 << (index & 63))); | touchesDown = (touchesDown | (1 << (index & 63))); | ||||
currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier); | currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier); | ||||
handleMouseEvent (index, pos, currentModifiers.withoutMouseButtons() | |||||
.withFlags (ModifierKeys::leftButtonModifier), time); | |||||
handleMouseEvent (index, pos, currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier), | |||||
MouseInputSource::invalidPressure, time); | |||||
} | } | ||||
void handleMouseUpCallback (int index, Point<float> pos, int64 time) | void handleMouseUpCallback (int index, Point<float> pos, int64 time) | ||||
@@ -361,7 +361,7 @@ public: | |||||
if (touchesDown == 0) | if (touchesDown == 0) | ||||
currentModifiers = currentModifiers.withoutMouseButtons(); | currentModifiers = currentModifiers.withoutMouseButtons(); | ||||
handleMouseEvent (index, pos, currentModifiers.withoutMouseButtons(), time); | |||||
handleMouseEvent (index, pos, currentModifiers.withoutMouseButtons(), MouseInputSource::invalidPressure, time); | |||||
} | } | ||||
void handleKeyDownCallback (int k, int kc) | void handleKeyDownCallback (int k, int kc) | ||||
@@ -767,7 +767,11 @@ void UIViewComponentPeer::handleTouches (UIEvent* event, const bool isDown, cons | |||||
{ | { | ||||
UITouch* touch = [touches objectAtIndex: i]; | UITouch* touch = [touches objectAtIndex: i]; | ||||
#if defined (__IPHONE_9_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_9_0 | |||||
if ([touch phase] == UITouchPhaseStationary && touch.maximumPossibleForce <= 0) | |||||
#else | |||||
if ([touch phase] == UITouchPhaseStationary) | if ([touch phase] == UITouchPhaseStationary) | ||||
#endif | |||||
continue; | continue; | ||||
CGPoint p = [touch locationInView: view]; | CGPoint p = [touch locationInView: view]; | ||||
@@ -788,7 +792,9 @@ void UIViewComponentPeer::handleTouches (UIEvent* event, const bool isDown, cons | |||||
modsToSend = currentModifiers; | modsToSend = currentModifiers; | ||||
// this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before. | // 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(), time); | |||||
handleMouseEvent (touchIndex, pos, modsToSend.withoutMouseButtons(), | |||||
MouseInputSource::invalidPressure, time); | |||||
if (! isValidPeer (this)) // (in case this component was deleted by the event) | if (! isValidPeer (this)) // (in case this component was deleted by the event) | ||||
return; | return; | ||||
} | } | ||||
@@ -810,13 +816,24 @@ void UIViewComponentPeer::handleTouches (UIEvent* event, const bool isDown, cons | |||||
modsToSend = currentModifiers = currentModifiers.withoutMouseButtons(); | modsToSend = currentModifiers = currentModifiers.withoutMouseButtons(); | ||||
} | } | ||||
handleMouseEvent (touchIndex, pos, modsToSend, time); | |||||
float pressure = MouseInputSource::invalidPressure; | |||||
#if defined (__IPHONE_9_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_9_0 | |||||
if (touch.maximumPossibleForce > 0) | |||||
// NB: other devices return 0 or 1.0 if pressure is unknown, so we'll clip our value to a believable range: | |||||
pressure = jlimit (0.0001f, 0.9999f, (float) (touch.force / touch.maximumPossibleForce)); | |||||
#endif | |||||
handleMouseEvent (touchIndex, pos, modsToSend, pressure, time); | |||||
if (! isValidPeer (this)) // (in case this component was deleted by the event) | if (! isValidPeer (this)) // (in case this component was deleted by the event) | ||||
return; | return; | ||||
if (isUp || isCancel) | if (isUp || isCancel) | ||||
{ | { | ||||
handleMouseEvent (touchIndex, Point<float> (-1.0f, -1.0f), modsToSend, time); | |||||
handleMouseEvent (touchIndex, Point<float> (-1.0f, -1.0f), | |||||
modsToSend, MouseInputSource::invalidPressure, time); | |||||
if (! isValidPeer (this)) | if (! isValidPeer (this)) | ||||
return; | return; | ||||
} | } | ||||
@@ -2215,7 +2215,8 @@ public: | |||||
{ | { | ||||
currentModifiers = currentModifiers.withFlags (buttonModifierFlag); | currentModifiers = currentModifiers.withFlags (buttonModifierFlag); | ||||
toFront (true); | toFront (true); | ||||
handleMouseEvent (0, getMousePos (buttonPressEvent), currentModifiers, getEventTime (buttonPressEvent)); | |||||
handleMouseEvent (0, getMousePos (buttonPressEvent), currentModifiers, | |||||
MouseInputSource::invalidPressure, getEventTime (buttonPressEvent)); | |||||
} | } | ||||
void handleButtonPressEvent (const XButtonPressedEvent& buttonPressEvent) | void handleButtonPressEvent (const XButtonPressedEvent& buttonPressEvent) | ||||
@@ -2253,7 +2254,8 @@ public: | |||||
if (dragState.dragging) | if (dragState.dragging) | ||||
handleExternalDragButtonReleaseEvent(); | handleExternalDragButtonReleaseEvent(); | ||||
handleMouseEvent (0, getMousePos (buttonRelEvent), currentModifiers, getEventTime (buttonRelEvent)); | |||||
handleMouseEvent (0, getMousePos (buttonRelEvent), currentModifiers, | |||||
MouseInputSource::invalidPressure, getEventTime (buttonRelEvent)); | |||||
clearLastMousePos(); | clearLastMousePos(); | ||||
} | } | ||||
@@ -2267,7 +2269,8 @@ public: | |||||
if (dragState.dragging) | if (dragState.dragging) | ||||
handleExternalDragMotionNotify(); | handleExternalDragMotionNotify(); | ||||
handleMouseEvent (0, getMousePos (movedEvent), currentModifiers, getEventTime (movedEvent)); | |||||
handleMouseEvent (0, getMousePos (movedEvent), currentModifiers, | |||||
MouseInputSource::invalidPressure, getEventTime (movedEvent)); | |||||
} | } | ||||
void handleEnterNotifyEvent (const XEnterWindowEvent& enterEvent) | void handleEnterNotifyEvent (const XEnterWindowEvent& enterEvent) | ||||
@@ -2280,7 +2283,8 @@ public: | |||||
if (! currentModifiers.isAnyMouseButtonDown()) | if (! currentModifiers.isAnyMouseButtonDown()) | ||||
{ | { | ||||
updateKeyModifiers ((int) enterEvent.state); | updateKeyModifiers ((int) enterEvent.state); | ||||
handleMouseEvent (0, getMousePos (enterEvent), currentModifiers, getEventTime (enterEvent)); | |||||
handleMouseEvent (0, getMousePos (enterEvent), currentModifiers, | |||||
MouseInputSource::invalidPressure, getEventTime (enterEvent)); | |||||
} | } | ||||
} | } | ||||
@@ -2293,7 +2297,8 @@ public: | |||||
|| leaveEvent.mode == NotifyUngrab) | || leaveEvent.mode == NotifyUngrab) | ||||
{ | { | ||||
updateKeyModifiers ((int) leaveEvent.state); | updateKeyModifiers ((int) leaveEvent.state); | ||||
handleMouseEvent (0, getMousePos (leaveEvent), currentModifiers, getEventTime (leaveEvent)); | |||||
handleMouseEvent (0, getMousePos (leaveEvent), currentModifiers, | |||||
MouseInputSource::invalidPressure, getEventTime (leaveEvent)); | |||||
} | } | ||||
} | } | ||||
@@ -587,7 +587,8 @@ public: | |||||
sendMouseEvent (ev); | sendMouseEvent (ev); | ||||
else | else | ||||
// moved into another window which overlaps this one, so trigger an exit | // moved into another window which overlaps this one, so trigger an exit | ||||
handleMouseEvent (0, Point<float> (-1.0f, -1.0f), currentModifiers, getMouseTime (ev)); | |||||
handleMouseEvent (0, Point<float> (-1.0f, -1.0f), currentModifiers, | |||||
getMousePressure (ev), getMouseTime (ev)); | |||||
showArrowCursorIfNeeded(); | showArrowCursorIfNeeded(); | ||||
} | } | ||||
@@ -678,7 +679,8 @@ public: | |||||
void sendMouseEvent (NSEvent* ev) | void sendMouseEvent (NSEvent* ev) | ||||
{ | { | ||||
updateModifiers (ev); | updateModifiers (ev); | ||||
handleMouseEvent (0, getMousePos (ev, view), currentModifiers, getMouseTime (ev)); | |||||
handleMouseEvent (0, getMousePos (ev, view), currentModifiers, | |||||
getMousePressure (ev), getMouseTime (ev)); | |||||
} | } | ||||
bool handleKeyEvent (NSEvent* ev, bool isKeyDown) | bool handleKeyEvent (NSEvent* ev, bool isKeyDown) | ||||
@@ -1080,10 +1082,15 @@ public: | |||||
return keyCode; | return keyCode; | ||||
} | } | ||||
static int64 getMouseTime (NSEvent* e) | |||||
static int64 getMouseTime (NSEvent* e) noexcept | |||||
{ | { | ||||
return (Time::currentTimeMillis() - Time::getMillisecondCounter()) | return (Time::currentTimeMillis() - Time::getMillisecondCounter()) | ||||
+ (int64) ([e timestamp] * 1000.0); | |||||
+ (int64) ([e timestamp] * 1000.0); | |||||
} | |||||
static float getMousePressure (NSEvent* e) noexcept | |||||
{ | |||||
return (float) e.pressure; | |||||
} | } | ||||
static Point<float> getMousePos (NSEvent* e, NSView* view) | static Point<float> getMousePos (NSEvent* e, NSView* view) | ||||
@@ -1663,9 +1663,9 @@ private: | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
void doMouseEvent (Point<float> position) | |||||
void doMouseEvent (Point<float> position, float pressure) | |||||
{ | { | ||||
handleMouseEvent (0, position, currentModifiers, getMouseEventTime()); | |||||
handleMouseEvent (0, position, currentModifiers, pressure, getMouseEventTime()); | |||||
} | } | ||||
StringArray getAvailableRenderingEngines() override | StringArray getAvailableRenderingEngines() override | ||||
@@ -1760,7 +1760,7 @@ private: | |||||
if (now >= lastMouseTime + minTimeBetweenMouses) | if (now >= lastMouseTime + minTimeBetweenMouses) | ||||
{ | { | ||||
lastMouseTime = now; | lastMouseTime = now; | ||||
doMouseEvent (position); | |||||
doMouseEvent (position, MouseInputSource::invalidPressure); | |||||
} | } | ||||
} | } | ||||
@@ -1780,7 +1780,7 @@ private: | |||||
updateModifiersFromWParam (wParam); | updateModifiersFromWParam (wParam); | ||||
isDragging = true; | isDragging = true; | ||||
doMouseEvent (position); | |||||
doMouseEvent (position, MouseInputSource::invalidPressure); | |||||
} | } | ||||
} | } | ||||
@@ -1801,7 +1801,7 @@ private: | |||||
// NB: under some circumstances (e.g. double-clicking a native title bar), a mouse-up can | // NB: under some circumstances (e.g. double-clicking a native title bar), a mouse-up can | ||||
// arrive without a mouse-down, so in that case we need to avoid sending a message. | // arrive without a mouse-down, so in that case we need to avoid sending a message. | ||||
if (wasDragging) | if (wasDragging) | ||||
doMouseEvent (position); | |||||
doMouseEvent (position, MouseInputSource::invalidPressure); | |||||
} | } | ||||
void doCaptureChanged() | void doCaptureChanged() | ||||
@@ -1821,7 +1821,7 @@ private: | |||||
void doMouseExit() | void doMouseExit() | ||||
{ | { | ||||
isMouseOver = false; | isMouseOver = false; | ||||
doMouseEvent (getCurrentMousePos()); | |||||
doMouseEvent (getCurrentMousePos(), MouseInputSource::invalidPressure); | |||||
} | } | ||||
ComponentPeer* findPeerUnderMouse (Point<float>& localPos) | ComponentPeer* findPeerUnderMouse (Point<float>& localPos) | ||||
@@ -1925,6 +1925,7 @@ private: | |||||
const int64 time = getMouseEventTime(); | const int64 time = getMouseEventTime(); | ||||
const Point<float> pos (globalToLocal (Point<float> (static_cast<float> (TOUCH_COORD_TO_PIXEL (touch.x)), | const Point<float> pos (globalToLocal (Point<float> (static_cast<float> (TOUCH_COORD_TO_PIXEL (touch.x)), | ||||
static_cast<float> (TOUCH_COORD_TO_PIXEL (touch.y))))); | static_cast<float> (TOUCH_COORD_TO_PIXEL (touch.y))))); | ||||
const float pressure = MouseInputSource::invalidPressure; | |||||
ModifierKeys modsToSend (currentModifiers); | ModifierKeys modsToSend (currentModifiers); | ||||
if (isDown) | if (isDown) | ||||
@@ -1932,9 +1933,10 @@ private: | |||||
currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier); | currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier); | ||||
modsToSend = currentModifiers; | 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.toFloat(), modsToSend.withoutMouseButtons(), time); | |||||
if (! isValidPeer (this)) // (in case this component was deleted by the event) | |||||
// this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before. | |||||
handleMouseEvent (touchIndex, pos.toFloat(), modsToSend.withoutMouseButtons(), pressure, time); | |||||
if (! isValidPeer (this)) // (in case this component was deleted by the event) | |||||
return false; | return false; | ||||
} | } | ||||
else if (isUp) | else if (isUp) | ||||
@@ -1956,13 +1958,15 @@ private: | |||||
currentModifiers = currentModifiers.withoutMouseButtons(); | currentModifiers = currentModifiers.withoutMouseButtons(); | ||||
} | } | ||||
handleMouseEvent (touchIndex, pos.toFloat(), modsToSend, time); | |||||
handleMouseEvent (touchIndex, pos.toFloat(), modsToSend, pressure, time); | |||||
if (! isValidPeer (this)) // (in case this component was deleted by the event) | if (! isValidPeer (this)) // (in case this component was deleted by the event) | ||||
return false; | return false; | ||||
if (isUp || isCancel) | if (isUp || isCancel) | ||||
{ | { | ||||
handleMouseEvent (touchIndex, Point<float> (-10.0f, -10.0f), currentModifiers, time); | |||||
handleMouseEvent (touchIndex, Point<float> (-10.0f, -10.0f), currentModifiers, pressure, time); | |||||
if (! isValidPeer (this)) | if (! isValidPeer (this)) | ||||
return false; | return false; | ||||
} | } | ||||
@@ -2248,7 +2252,7 @@ private: | |||||
if (contains (pos.roundToInt(), false)) | if (contains (pos.roundToInt(), false)) | ||||
{ | { | ||||
doMouseEvent (pos); | |||||
doMouseEvent (pos, MouseInputSource::invalidPressure); | |||||
if (! isValidPeer (this)) | if (! isValidPeer (this)) | ||||
return true; | return true; | ||||
@@ -85,10 +85,10 @@ bool ComponentPeer::isKioskMode() const | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
void ComponentPeer::handleMouseEvent (int touchIndex, Point<float> pos, ModifierKeys newMods, int64 time) | |||||
void ComponentPeer::handleMouseEvent (int touchIndex, Point<float> pos, ModifierKeys newMods, float newPressure, int64 time) | |||||
{ | { | ||||
if (MouseInputSource* mouse = Desktop::getInstance().mouseSources->getOrCreateMouseInputSource (touchIndex)) | if (MouseInputSource* mouse = Desktop::getInstance().mouseSources->getOrCreateMouseInputSource (touchIndex)) | ||||
MouseInputSource (*mouse).handleEvent (*this, pos, time, newMods); | |||||
MouseInputSource (*mouse).handleEvent (*this, pos, time, newMods, newPressure); | |||||
} | } | ||||
void ComponentPeer::handleMouseWheel (int touchIndex, Point<float> pos, int64 time, const MouseWheelDetails& wheel) | void ComponentPeer::handleMouseWheel (int touchIndex, Point<float> pos, int64 time, const MouseWheelDetails& wheel) | ||||
@@ -306,7 +306,7 @@ public: | |||||
virtual void setAlpha (float newAlpha) = 0; | virtual void setAlpha (float newAlpha) = 0; | ||||
//============================================================================== | //============================================================================== | ||||
void handleMouseEvent (int touchIndex, Point<float> positionWithinPeer, ModifierKeys newMods, int64 time); | |||||
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 handleMouseWheel (int touchIndex, Point<float> positionWithinPeer, int64 time, const MouseWheelDetails&); | ||||
void handleMagnifyGesture (int touchIndex, Point<float> positionWithinPeer, int64 time, float scaleFactor); | void handleMagnifyGesture (int touchIndex, Point<float> positionWithinPeer, int64 time, float scaleFactor); | ||||
@@ -104,6 +104,7 @@ public: | |||||
const Time now (Time::getCurrentTime()); | const Time now (Time::getCurrentTime()); | ||||
MouseInputSource mouseSource = Desktop::getInstance().getMainMouseSource(); | MouseInputSource mouseSource = Desktop::getInstance().getMainMouseSource(); | ||||
const float pressure = (float) e.pressure; | |||||
if (isLeft || isRight) // Only mouse up is sent by the OS, so simulate a down/up | if (isLeft || isRight) // Only mouse up is sent by the OS, so simulate a down/up | ||||
{ | { | ||||
@@ -113,17 +114,17 @@ public: | |||||
owner.mouseDown (MouseEvent (mouseSource, Point<float>(), | owner.mouseDown (MouseEvent (mouseSource, Point<float>(), | ||||
eventMods.withFlags (isLeft ? ModifierKeys::leftButtonModifier | eventMods.withFlags (isLeft ? ModifierKeys::leftButtonModifier | ||||
: ModifierKeys::rightButtonModifier), | : ModifierKeys::rightButtonModifier), | ||||
&owner, &owner, now, | |||||
pressure, &owner, &owner, now, | |||||
Point<float>(), now, 1, false)); | Point<float>(), now, 1, false)); | ||||
owner.mouseUp (MouseEvent (mouseSource, Point<float>(), eventMods.withoutMouseButtons(), | owner.mouseUp (MouseEvent (mouseSource, Point<float>(), eventMods.withoutMouseButtons(), | ||||
&owner, &owner, now, | |||||
pressure, &owner, &owner, now, | |||||
Point<float>(), now, 1, false)); | Point<float>(), now, 1, false)); | ||||
} | } | ||||
else if (type == NSMouseMoved) | else if (type == NSMouseMoved) | ||||
{ | { | ||||
owner.mouseMove (MouseEvent (mouseSource, Point<float>(), eventMods, | owner.mouseMove (MouseEvent (mouseSource, Point<float>(), eventMods, | ||||
&owner, &owner, now, | |||||
pressure, &owner, &owner, now, | |||||
Point<float>(), now, 1, false)); | Point<float>(), now, 1, false)); | ||||
} | } | ||||
} | } | ||||
@@ -189,6 +189,7 @@ namespace ActiveXHelpers | |||||
peer->handleMouseEvent (0, Point<int> (GET_X_LPARAM (lParam) + activeXRect.left - peerRect.left, | peer->handleMouseEvent (0, Point<int> (GET_X_LPARAM (lParam) + activeXRect.left - peerRect.left, | ||||
GET_Y_LPARAM (lParam) + activeXRect.top - peerRect.top).toFloat(), | GET_Y_LPARAM (lParam) + activeXRect.top - peerRect.top).toFloat(), | ||||
ModifierKeys::getCurrentModifiersRealtime(), | ModifierKeys::getCurrentModifiersRealtime(), | ||||
MouseInputSource::invalidPressure, | |||||
getMouseEventTime()); | getMouseEventTime()); | ||||
break; | break; | ||||
@@ -111,8 +111,8 @@ public: | |||||
const Time eventTime (getMouseEventTime()); | const Time eventTime (getMouseEventTime()); | ||||
const MouseEvent e (Desktop::getInstance().getMainMouseSource(), | const MouseEvent e (Desktop::getInstance().getMainMouseSource(), | ||||
Point<float>(), eventMods, &owner, &owner, eventTime, | |||||
Point<float>(), eventTime, 1, false); | |||||
Point<float>(), eventMods, MouseInputSource::invalidPressure, | |||||
&owner, &owner, eventTime, Point<float>(), eventTime, 1, false); | |||||
if (lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN) | if (lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN) | ||||
{ | { | ||||