| @@ -138,6 +138,11 @@ public: | |||||
| } | } | ||||
| } | } | ||||
| void mouseMagnify (const MouseEvent&, float zoomFactor) | |||||
| { | |||||
| owner.sizeSlider->setValue (owner.sizeSlider->getValue() * zoomFactor); | |||||
| } | |||||
| private: | private: | ||||
| RenderingTestComponent& owner; | RenderingTestComponent& owner; | ||||
| double averageTime; | double averageTime; | ||||
| @@ -151,13 +156,13 @@ private: | |||||
| float speeds[8]; | float speeds[8]; | ||||
| Time lastSVGLoadTime; | Time lastSVGLoadTime; | ||||
| const AffineTransform getTransform() | |||||
| AffineTransform getTransform() | |||||
| { | { | ||||
| return AffineTransform::rotation ((float) owner.angleSlider->getValue() / (180.0f / float_Pi)) | return AffineTransform::rotation ((float) owner.angleSlider->getValue() / (180.0f / float_Pi)) | ||||
| .scaled ((float) owner.sizeSlider->getValue(), | |||||
| (float) owner.sizeSlider->getValue()) | |||||
| .translated (getWidth() / 2 + (float) owner.xSlider->getValue(), | |||||
| getHeight() / 2 + (float) owner.ySlider->getValue()); | |||||
| .scaled ((float) owner.sizeSlider->getValue(), | |||||
| (float) owner.sizeSlider->getValue()) | |||||
| .translated (getWidth() / 2 + (float) owner.xSlider->getValue(), | |||||
| getHeight() / 2 + (float) owner.ySlider->getValue()); | |||||
| } | } | ||||
| void clipToRectangle (Graphics& g) | void clipToRectangle (Graphics& g) | ||||
| @@ -2151,6 +2151,12 @@ void Component::mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& wh | |||||
| parentComponent->mouseWheelMove (e.getEventRelativeTo (parentComponent), wheel); | parentComponent->mouseWheelMove (e.getEventRelativeTo (parentComponent), wheel); | ||||
| } | } | ||||
| void Component::mouseMagnify (const MouseEvent& e, float magnifyAmount) | |||||
| { | |||||
| // the base class just passes this event up to its parent.. | |||||
| if (parentComponent != nullptr) | |||||
| parentComponent->mouseMagnify (e.getEventRelativeTo (parentComponent), magnifyAmount); | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| void Component::resized() {} | void Component::resized() {} | ||||
| @@ -2477,6 +2483,18 @@ void Component::internalMouseWheel (MouseInputSource& source, const Point<int>& | |||||
| } | } | ||||
| } | } | ||||
| void Component::internalMagnifyGesture (MouseInputSource& source, const Point<int>& relativePos, | |||||
| const Time& time, float amount) | |||||
| { | |||||
| if (! isCurrentlyBlockedByAnotherModalComponent()) | |||||
| { | |||||
| const MouseEvent me (source, relativePos, source.getCurrentModifiers(), | |||||
| this, this, time, relativePos, time, 0, false); | |||||
| mouseMagnify (me, amount); | |||||
| } | |||||
| } | |||||
| void Component::sendFakeMouseMove() const | void Component::sendFakeMouseMove() const | ||||
| { | { | ||||
| MouseInputSource& mainMouse = Desktop::getInstance().getMainMouseSource(); | MouseInputSource& mainMouse = Desktop::getInstance().getMainMouseSource(); | ||||
| @@ -1559,6 +1559,18 @@ public: | |||||
| virtual void mouseWheelMove (const MouseEvent& event, | virtual void mouseWheelMove (const MouseEvent& event, | ||||
| const MouseWheelDetails& wheel); | const MouseWheelDetails& wheel); | ||||
| /** Called when a pinch-to-zoom mouse-gesture is used. | |||||
| If not overridden, a component will forward this message to its parent, so | |||||
| that parent components can collect gesture messages that are unused by child | |||||
| components. | |||||
| @param scaleFactor a multiplier to indicate by how much the size of the target | |||||
| should be changed. A value of 1.0 would indicate no change, | |||||
| values greater than 1.0 mean it should be enlarged. | |||||
| */ | |||||
| virtual void mouseMagnify (const MouseEvent& event, float scaleFactor); | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Ensures that a non-stop stream of mouse-drag events will be sent during the | /** Ensures that a non-stop stream of mouse-drag events will be sent during the | ||||
| current mouse-drag operation. | current mouse-drag operation. | ||||
| @@ -2281,6 +2293,7 @@ private: | |||||
| void internalMouseDrag (MouseInputSource&, const Point<int>&, const Time&); | void internalMouseDrag (MouseInputSource&, const Point<int>&, const Time&); | ||||
| void internalMouseMove (MouseInputSource&, const Point<int>&, const Time&); | void internalMouseMove (MouseInputSource&, const Point<int>&, const Time&); | ||||
| void internalMouseWheel (MouseInputSource&, const Point<int>&, const Time&, const MouseWheelDetails&); | void internalMouseWheel (MouseInputSource&, const Point<int>&, const Time&, const MouseWheelDetails&); | ||||
| void internalMagnifyGesture (MouseInputSource&, const Point<int>&, const Time&, float); | |||||
| void internalBroughtToFront(); | void internalBroughtToFront(); | ||||
| void internalFocusGain (const FocusChangeType, const WeakReference<Component>&); | void internalFocusGain (const FocusChangeType, const WeakReference<Component>&); | ||||
| void internalFocusGain (const FocusChangeType); | void internalFocusGain (const FocusChangeType); | ||||
| @@ -82,48 +82,62 @@ public: | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| #if JUCE_DUMP_MOUSE_EVENTS | |||||
| #define JUCE_MOUSE_EVENT_DBG(desc) DBG ("Mouse " desc << " #" << source.getIndex() \ | |||||
| << ": " << comp->getLocalPoint (nullptr, screenPos).toString() \ | |||||
| << " - Comp: " << String::toHexString ((int) comp)); | |||||
| #else | |||||
| #define JUCE_MOUSE_EVENT_DBG(desc) | |||||
| #endif | |||||
| void sendMouseEnter (Component* const comp, const Point<int>& screenPos, const Time& time) | void sendMouseEnter (Component* const comp, const Point<int>& screenPos, const Time& time) | ||||
| { | { | ||||
| //DBG ("Mouse " + String (source.getIndex()) + " enter: " + comp->getLocalPoint (nullptr, screenPos).toString() + " - Comp: " + String::toHexString ((int) comp)); | |||||
| JUCE_MOUSE_EVENT_DBG ("enter") | |||||
| comp->internalMouseEnter (source, comp->getLocalPoint (nullptr, screenPos), time); | comp->internalMouseEnter (source, comp->getLocalPoint (nullptr, screenPos), time); | ||||
| } | } | ||||
| void sendMouseExit (Component* const comp, const Point<int>& screenPos, const Time& time) | void sendMouseExit (Component* const comp, const Point<int>& screenPos, const Time& time) | ||||
| { | { | ||||
| //DBG ("Mouse " + String (source.getIndex()) + " exit: " + comp->getLocalPoint (nullptr, screenPos).toString() + " - Comp: " + String::toHexString ((int) comp)); | |||||
| JUCE_MOUSE_EVENT_DBG ("exit") | |||||
| comp->internalMouseExit (source, comp->getLocalPoint (nullptr, screenPos), time); | comp->internalMouseExit (source, comp->getLocalPoint (nullptr, screenPos), time); | ||||
| } | } | ||||
| void sendMouseMove (Component* const comp, const Point<int>& screenPos, const Time& time) | void sendMouseMove (Component* const comp, const Point<int>& screenPos, const Time& time) | ||||
| { | { | ||||
| //DBG ("Mouse " + String (source.getIndex()) + " move: " + comp->getLocalPoint (nullptr, screenPos).toString() + " - Comp: " + String::toHexString ((int) comp)); | |||||
| JUCE_MOUSE_EVENT_DBG ("move") | |||||
| comp->internalMouseMove (source, comp->getLocalPoint (nullptr, screenPos), time); | comp->internalMouseMove (source, comp->getLocalPoint (nullptr, screenPos), time); | ||||
| } | } | ||||
| void sendMouseDown (Component* const comp, const Point<int>& screenPos, const Time& time) | void sendMouseDown (Component* const comp, const Point<int>& screenPos, const Time& time) | ||||
| { | { | ||||
| //DBG ("Mouse " + String (source.getIndex()) + " down: " + comp->getLocalPoint (nullptr, screenPos).toString() + " - Comp: " + String::toHexString ((int) comp)); | |||||
| JUCE_MOUSE_EVENT_DBG ("down") | |||||
| comp->internalMouseDown (source, comp->getLocalPoint (nullptr, screenPos), time); | comp->internalMouseDown (source, comp->getLocalPoint (nullptr, screenPos), time); | ||||
| } | } | ||||
| void sendMouseDrag (Component* const comp, const Point<int>& screenPos, const Time& time) | void sendMouseDrag (Component* const comp, const Point<int>& screenPos, const Time& time) | ||||
| { | { | ||||
| //DBG ("Mouse " + String (source.getIndex()) + " drag: " + comp->getLocalPoint (nullptr, screenPos).toString() + " - Comp: " + String::toHexString ((int) comp)); | |||||
| JUCE_MOUSE_EVENT_DBG ("drag") | |||||
| comp->internalMouseDrag (source, comp->getLocalPoint (nullptr, screenPos), time); | comp->internalMouseDrag (source, comp->getLocalPoint (nullptr, screenPos), time); | ||||
| } | } | ||||
| void sendMouseUp (Component* const comp, const Point<int>& screenPos, const Time& time, const ModifierKeys& oldMods) | void sendMouseUp (Component* const comp, const Point<int>& screenPos, const Time& time, const ModifierKeys& oldMods) | ||||
| { | { | ||||
| //DBG ("Mouse " + String (source.getIndex()) + " up: " + comp->getLocalPoint (nullptr, screenPos).toString() + " - Comp: " + String::toHexString ((int) comp)); | |||||
| JUCE_MOUSE_EVENT_DBG ("up") | |||||
| comp->internalMouseUp (source, comp->getLocalPoint (nullptr, screenPos), time, oldMods); | comp->internalMouseUp (source, comp->getLocalPoint (nullptr, screenPos), time, oldMods); | ||||
| } | } | ||||
| void sendMouseWheel (Component* const comp, const Point<int>& screenPos, const Time& time, const MouseWheelDetails& wheel) | void sendMouseWheel (Component* const comp, const Point<int>& screenPos, const Time& time, const MouseWheelDetails& wheel) | ||||
| { | { | ||||
| //DBG ("Mouse " + String (source.getIndex()) + " wheel: " + comp->getLocalPoint (nullptr, screenPos).toString() + " - Comp: " + String::toHexString ((int) comp)); | |||||
| JUCE_MOUSE_EVENT_DBG ("wheel") | |||||
| comp->internalMouseWheel (source, comp->getLocalPoint (nullptr, screenPos), time, wheel); | comp->internalMouseWheel (source, comp->getLocalPoint (nullptr, screenPos), time, wheel); | ||||
| } | } | ||||
| void sendMagnifyGesture (Component* const comp, const Point<int>& screenPos, const Time& time, const float amount) | |||||
| { | |||||
| JUCE_MOUSE_EVENT_DBG ("magnify") | |||||
| comp->internalMagnifyGesture (source, comp->getLocalPoint (nullptr, screenPos), time, amount); | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| // (returns true if the button change caused a modal event loop) | // (returns true if the button change caused a modal event loop) | ||||
| bool setButtons (const Point<int>& screenPos, const Time& time, const ModifierKeys& newButtonState) | bool setButtons (const Point<int>& screenPos, const Time& time, const ModifierKeys& newButtonState) | ||||
| @@ -276,24 +290,37 @@ public: | |||||
| } | } | ||||
| } | } | ||||
| void handleWheel (ComponentPeer* const peer, const Point<int>& positionWithinPeer, | |||||
| const Time& time, const MouseWheelDetails& wheel) | |||||
| Component* getTargetForGesture (ComponentPeer* const peer, const Point<int>& positionWithinPeer, | |||||
| const Time& time, Point<int>& screenPos) | |||||
| { | { | ||||
| jassert (peer != nullptr); | jassert (peer != nullptr); | ||||
| lastTime = time; | lastTime = time; | ||||
| ++mouseEventCounter; | ++mouseEventCounter; | ||||
| Desktop::getInstance().incrementMouseWheelCounter(); | |||||
| const Point<int> screenPos (peer->localToGlobal (positionWithinPeer)); | |||||
| screenPos = peer->localToGlobal (positionWithinPeer); | |||||
| setPeer (peer, screenPos, time); | setPeer (peer, screenPos, time); | ||||
| setScreenPos (screenPos, time, false); | setScreenPos (screenPos, time, false); | ||||
| triggerFakeMove(); | triggerFakeMove(); | ||||
| if (! isDragging()) | |||||
| { | |||||
| if (Component* current = getComponentUnderMouse()) | |||||
| sendMouseWheel (current, screenPos, time, wheel); | |||||
| } | |||||
| return isDragging() ? nullptr : getComponentUnderMouse(); | |||||
| } | |||||
| void handleWheel (ComponentPeer* const peer, const Point<int>& positionWithinPeer, | |||||
| const Time& time, const MouseWheelDetails& wheel) | |||||
| { | |||||
| Desktop::getInstance().incrementMouseWheelCounter(); | |||||
| Point<int> screenPos; | |||||
| if (Component* current = getTargetForGesture (peer, positionWithinPeer, time, screenPos)) | |||||
| sendMouseWheel (current, screenPos, time, wheel); | |||||
| } | |||||
| void handleMagnifyGesture (ComponentPeer* const peer, const Point<int>& positionWithinPeer, | |||||
| const Time& time, const float scaleFactor) | |||||
| { | |||||
| Point<int> screenPos; | |||||
| if (Component* current = getTargetForGesture (peer, positionWithinPeer, time, screenPos)) | |||||
| sendMagnifyGesture (current, screenPos, time, scaleFactor); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -518,3 +545,9 @@ void MouseInputSource::handleWheel (ComponentPeer* const peer, const Point<int>& | |||||
| { | { | ||||
| pimpl->handleWheel (peer, positionWithinPeer, Time (time), wheel); | pimpl->handleWheel (peer, positionWithinPeer, Time (time), wheel); | ||||
| } | } | ||||
| void MouseInputSource::handleMagnifyGesture (ComponentPeer* const peer, const Point<int>& positionWithinPeer, | |||||
| const int64 time, const float scaleFactor) | |||||
| { | |||||
| pimpl->handleMagnifyGesture (peer, positionWithinPeer, Time (time), scaleFactor); | |||||
| } | |||||
| @@ -166,9 +166,11 @@ public: | |||||
| //============================================================================== | //============================================================================== | ||||
| /** @internal */ | /** @internal */ | ||||
| void handleEvent (ComponentPeer*, const Point<int>& positionWithinPeer, int64 time, const ModifierKeys&); | |||||
| void handleEvent (ComponentPeer*, const Point<int>&, int64 time, const ModifierKeys&); | |||||
| /** @internal */ | /** @internal */ | ||||
| void handleWheel (ComponentPeer*, const Point<int>& positionWithinPeer, int64 time, const MouseWheelDetails&); | |||||
| void handleWheel (ComponentPeer*, const Point<int>&, int64 time, const MouseWheelDetails&); | |||||
| /** @internal */ | |||||
| void handleMagnifyGesture (ComponentPeer*, const Point<int>&, int64 time, float scaleFactor); | |||||
| private: | private: | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -626,6 +626,14 @@ public: | |||||
| handleMouseWheel (0, getMousePos (ev, view), getMouseTime (ev), wheel); | handleMouseWheel (0, getMousePos (ev, view), getMouseTime (ev), wheel); | ||||
| } | } | ||||
| void redirectMagnify (NSEvent* ev) | |||||
| { | |||||
| const float invScale = 1.0f - [ev magnification]; | |||||
| if (invScale != 0.0f) | |||||
| handleMagnifyGesture (0, getMousePos (ev, view), getMouseTime (ev), 1.0f / invScale); | |||||
| } | |||||
| void sendMouseEvent (NSEvent* ev) | void sendMouseEvent (NSEvent* ev) | ||||
| { | { | ||||
| updateModifiers (ev); | updateModifiers (ev); | ||||
| @@ -1347,6 +1355,7 @@ struct JuceNSViewClass : public ObjCClass <NSView> | |||||
| addMethod (@selector (otherMouseDragged:), mouseDragged, "v@:@"); | addMethod (@selector (otherMouseDragged:), mouseDragged, "v@:@"); | ||||
| addMethod (@selector (otherMouseUp:), mouseUp, "v@:@"); | addMethod (@selector (otherMouseUp:), mouseUp, "v@:@"); | ||||
| addMethod (@selector (scrollWheel:), scrollWheel, "v@:@"); | addMethod (@selector (scrollWheel:), scrollWheel, "v@:@"); | ||||
| addMethod (@selector (magnifyWithEvent:), magnify, "v@:@"); | |||||
| addMethod (@selector (acceptsFirstMouse:), acceptsFirstMouse, "v@:@"); | addMethod (@selector (acceptsFirstMouse:), acceptsFirstMouse, "v@:@"); | ||||
| addMethod (@selector (frameChanged:), frameChanged, "v@:@"); | addMethod (@selector (frameChanged:), frameChanged, "v@:@"); | ||||
| addMethod (@selector (viewDidMoveToWindow), viewDidMoveToWindow, "v@:"); | addMethod (@selector (viewDidMoveToWindow), viewDidMoveToWindow, "v@:"); | ||||
| @@ -1425,6 +1434,7 @@ private: | |||||
| static void mouseEntered (id self, SEL, NSEvent* ev) { if (NSViewComponentPeer* const p = getOwner (self)) p->redirectMouseEnter (ev); } | static void mouseEntered (id self, SEL, NSEvent* ev) { if (NSViewComponentPeer* const p = getOwner (self)) p->redirectMouseEnter (ev); } | ||||
| static void mouseExited (id self, SEL, NSEvent* ev) { if (NSViewComponentPeer* const p = getOwner (self)) p->redirectMouseExit (ev); } | static void mouseExited (id self, SEL, NSEvent* ev) { if (NSViewComponentPeer* const p = getOwner (self)) p->redirectMouseExit (ev); } | ||||
| static void scrollWheel (id self, SEL, NSEvent* ev) { if (NSViewComponentPeer* const p = getOwner (self)) p->redirectMouseWheel (ev); } | static void scrollWheel (id self, SEL, NSEvent* ev) { if (NSViewComponentPeer* const p = getOwner (self)) p->redirectMouseWheel (ev); } | ||||
| static void magnify (id self, SEL, NSEvent* ev) { if (NSViewComponentPeer* const p = getOwner (self)) p->redirectMagnify (ev); } | |||||
| static BOOL acceptsFirstMouse (id, SEL, NSEvent*) { return YES; } | static BOOL acceptsFirstMouse (id, SEL, NSEvent*) { return YES; } | ||||
| @@ -77,8 +77,9 @@ bool Desktop::canUseSemiTransparentWindows() noexcept | |||||
| #define TOUCHEVENTF_DOWN 0x0002 | #define TOUCHEVENTF_DOWN 0x0002 | ||||
| #define TOUCHEVENTF_UP 0x0004 | #define TOUCHEVENTF_UP 0x0004 | ||||
| DECLARE_HANDLE (HTOUCHINPUT); | DECLARE_HANDLE (HTOUCHINPUT); | ||||
| DECLARE_HANDLE (HGESTUREINFO); | |||||
| typedef struct tagTOUCHINPUT | |||||
| struct TOUCHINPUT | |||||
| { | { | ||||
| LONG x; | LONG x; | ||||
| LONG y; | LONG y; | ||||
| @@ -90,16 +91,32 @@ bool Desktop::canUseSemiTransparentWindows() noexcept | |||||
| ULONG_PTR dwExtraInfo; | ULONG_PTR dwExtraInfo; | ||||
| DWORD cxContact; | DWORD cxContact; | ||||
| DWORD cyContact; | DWORD cyContact; | ||||
| } TOUCHINPUT, *PTOUCHINPUT; | |||||
| }; | |||||
| struct GESTUREINFO | |||||
| { | |||||
| UINT cbSize; | |||||
| DWORD dwFlags; | |||||
| DWORD dwID; | |||||
| HWND hwndTarget; | |||||
| POINTS ptsLocation; | |||||
| DWORD dwInstanceID; | |||||
| DWORD dwSequenceID; | |||||
| ULONGLONG ullArguments; | |||||
| UINT cbExtraArgs; | |||||
| }; | |||||
| #endif | #endif | ||||
| typedef BOOL (WINAPI* RegisterTouchWindowFunc) (HWND, ULONG); | typedef BOOL (WINAPI* RegisterTouchWindowFunc) (HWND, ULONG); | ||||
| typedef BOOL (WINAPI* GetTouchInputInfoFunc) (HTOUCHINPUT, UINT, PTOUCHINPUT, int); | |||||
| typedef BOOL (WINAPI* GetTouchInputInfoFunc) (HTOUCHINPUT, UINT, TOUCHINPUT*, int); | |||||
| typedef BOOL (WINAPI* CloseTouchInputHandleFunc) (HTOUCHINPUT); | typedef BOOL (WINAPI* CloseTouchInputHandleFunc) (HTOUCHINPUT); | ||||
| typedef BOOL (WINAPI* GetGestureInfoFunc) (HGESTUREINFO, GESTUREINFO*); | |||||
| static RegisterTouchWindowFunc registerTouchWindow = nullptr; | static RegisterTouchWindowFunc registerTouchWindow = nullptr; | ||||
| static GetTouchInputInfoFunc getTouchInputInfo = nullptr; | static GetTouchInputInfoFunc getTouchInputInfo = nullptr; | ||||
| static CloseTouchInputHandleFunc closeTouchInputHandle = nullptr; | static CloseTouchInputHandleFunc closeTouchInputHandle = nullptr; | ||||
| static GetGestureInfoFunc getGestureInfo = nullptr; | |||||
| static bool hasCheckedForMultiTouch = false; | static bool hasCheckedForMultiTouch = false; | ||||
| @@ -112,6 +129,7 @@ static bool canUseMultiTouch() | |||||
| registerTouchWindow = (RegisterTouchWindowFunc) getUser32Function ("RegisterTouchWindow"); | registerTouchWindow = (RegisterTouchWindowFunc) getUser32Function ("RegisterTouchWindow"); | ||||
| getTouchInputInfo = (GetTouchInputInfoFunc) getUser32Function ("GetTouchInputInfo"); | getTouchInputInfo = (GetTouchInputInfoFunc) getUser32Function ("GetTouchInputInfo"); | ||||
| closeTouchInputHandle = (CloseTouchInputHandleFunc) getUser32Function ("CloseTouchInputHandle"); | closeTouchInputHandle = (CloseTouchInputHandleFunc) getUser32Function ("CloseTouchInputHandle"); | ||||
| getGestureInfo = (GetGestureInfoFunc) getUser32Function ("GetGestureInfo"); | |||||
| } | } | ||||
| return registerTouchWindow != nullptr; | return registerTouchWindow != nullptr; | ||||
| @@ -473,6 +491,7 @@ public: | |||||
| parentToAddTo (parent), | parentToAddTo (parent), | ||||
| currentRenderingEngine (softwareRenderingEngine), | currentRenderingEngine (softwareRenderingEngine), | ||||
| lastPaintTime (0), | lastPaintTime (0), | ||||
| lastMagnifySize (0), | |||||
| fullScreen (false), | fullScreen (false), | ||||
| isDragging (false), | isDragging (false), | ||||
| isMouseOver (false), | isMouseOver (false), | ||||
| @@ -1070,6 +1089,7 @@ private: | |||||
| ScopedPointer<Direct2DLowLevelGraphicsContext> direct2DContext; | ScopedPointer<Direct2DLowLevelGraphicsContext> direct2DContext; | ||||
| #endif | #endif | ||||
| uint32 lastPaintTime; | uint32 lastPaintTime; | ||||
| ULONGLONG lastMagnifySize; | |||||
| bool fullScreen, isDragging, isMouseOver, hasCreatedCaret, constrainerIsResizing; | bool fullScreen, isDragging, isMouseOver, hasCreatedCaret, constrainerIsResizing; | ||||
| BorderSize<int> windowBorder; | BorderSize<int> windowBorder; | ||||
| HICON currentWindowIcon; | HICON currentWindowIcon; | ||||
| @@ -1690,10 +1710,9 @@ private: | |||||
| doMouseEvent (getCurrentMousePos()); | doMouseEvent (getCurrentMousePos()); | ||||
| } | } | ||||
| void doMouseWheel (const Point<int>& globalPos, const WPARAM wParam, const bool isVertical) | |||||
| ComponentPeer* findPeerUnderMouse (Point<int>& localPos) | |||||
| { | { | ||||
| updateKeyModifiers(); | |||||
| const float amount = jlimit (-1000.0f, 1000.0f, 0.5f * (short) HIWORD (wParam)); | |||||
| const Point<int> globalPos (getCurrentMousePosGlobal()); | |||||
| // Because Windows stupidly sends all wheel events to the window with the keyboard | // Because Windows stupidly sends all wheel events to the window with the keyboard | ||||
| // focus, we have to redirect them here according to the mouse pos.. | // focus, we have to redirect them here according to the mouse pos.. | ||||
| @@ -1703,13 +1722,60 @@ private: | |||||
| if (peer == nullptr) | if (peer == nullptr) | ||||
| peer = this; | peer = this; | ||||
| localPos = peer->globalToLocal (globalPos); | |||||
| return peer; | |||||
| } | |||||
| void doMouseWheel (const WPARAM wParam, const bool isVertical) | |||||
| { | |||||
| updateKeyModifiers(); | |||||
| const float amount = jlimit (-1000.0f, 1000.0f, 0.5f * (short) HIWORD (wParam)); | |||||
| MouseWheelDetails wheel; | MouseWheelDetails wheel; | ||||
| wheel.deltaX = isVertical ? 0.0f : amount / -256.0f; | wheel.deltaX = isVertical ? 0.0f : amount / -256.0f; | ||||
| wheel.deltaY = isVertical ? amount / 256.0f : 0.0f; | wheel.deltaY = isVertical ? amount / 256.0f : 0.0f; | ||||
| wheel.isReversed = false; | wheel.isReversed = false; | ||||
| wheel.isSmooth = false; | wheel.isSmooth = false; | ||||
| peer->handleMouseWheel (0, peer->globalToLocal (globalPos), getMouseEventTime(), wheel); | |||||
| Point<int> localPos; | |||||
| if (ComponentPeer* const peer = findPeerUnderMouse (localPos)) | |||||
| peer->handleMouseWheel (0, localPos, getMouseEventTime(), wheel); | |||||
| } | |||||
| bool doGestureEvent (LPARAM lParam) | |||||
| { | |||||
| GESTUREINFO gi; | |||||
| zerostruct (gi); | |||||
| gi.cbSize = sizeof (gi); | |||||
| if (getGestureInfo != nullptr && getGestureInfo ((HGESTUREINFO) lParam, &gi)) | |||||
| { | |||||
| updateKeyModifiers(); | |||||
| Point<int> localPos; | |||||
| if (ComponentPeer* const peer = findPeerUnderMouse (localPos)) | |||||
| { | |||||
| switch (gi.dwID) | |||||
| { | |||||
| case 3: /*GID_ZOOM*/ | |||||
| if (gi.dwFlags != 1 /*GF_BEGIN*/ && lastMagnifySize > 0) | |||||
| peer->handleMagnifyGesture (0, localPos, getMouseEventTime(), | |||||
| (float) (gi.ullArguments / (double) lastMagnifySize)); | |||||
| lastMagnifySize = gi.ullArguments; | |||||
| return true; | |||||
| case 4: /*GID_PAN*/ | |||||
| case 5: /*GID_ROTATE*/ | |||||
| case 6: /*GID_TWOFINGERTAP*/ | |||||
| case 7: /*GID_PRESSANDTAP*/ | |||||
| default: | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| return false; | |||||
| } | } | ||||
| void doTouchEvent (const int numInputs, HTOUCHINPUT eventHandle) | void doTouchEvent (const int numInputs, HTOUCHINPUT eventHandle) | ||||
| @@ -2226,7 +2292,7 @@ private: | |||||
| case 0x020A: /* WM_MOUSEWHEEL */ | case 0x020A: /* WM_MOUSEWHEEL */ | ||||
| case 0x020E: /* WM_MOUSEHWHEEL */ | case 0x020E: /* WM_MOUSEHWHEEL */ | ||||
| doMouseWheel (getCurrentMousePosGlobal(), wParam, message == 0x020A); | |||||
| doMouseWheel (wParam, message == 0x020A); | |||||
| return 0; | return 0; | ||||
| case WM_TOUCH: | case WM_TOUCH: | ||||
| @@ -2236,6 +2302,12 @@ private: | |||||
| doTouchEvent ((int) wParam, (HTOUCHINPUT) lParam); | doTouchEvent ((int) wParam, (HTOUCHINPUT) lParam); | ||||
| return 0; | return 0; | ||||
| case 0x119: /* WM_GESTURE */ | |||||
| if (doGestureEvent (lParam)) | |||||
| return 0; | |||||
| break; | |||||
| //============================================================================== | //============================================================================== | ||||
| case WM_SIZING: return handleSizeConstraining (*(RECT*) lParam, wParam); | case WM_SIZING: return handleSizeConstraining (*(RECT*) lParam, wParam); | ||||
| case WM_WINDOWPOSCHANGING: return handlePositionChanging (*(WINDOWPOS*) lParam); | case WM_WINDOWPOSCHANGING: return handlePositionChanging (*(WINDOWPOS*) lParam); | ||||
| @@ -113,6 +113,13 @@ void ComponentPeer::handleMouseWheel (const int touchIndex, const Point<int>& po | |||||
| mouse->handleWheel (this, positionWithinPeer, time, wheel); | mouse->handleWheel (this, positionWithinPeer, time, wheel); | ||||
| } | } | ||||
| void ComponentPeer::handleMagnifyGesture (const int touchIndex, const Point<int>& positionWithinPeer, | |||||
| const int64 time, const float scaleFactor) | |||||
| { | |||||
| if (MouseInputSource* mouse = getOrCreateMouseInputSource (touchIndex)) | |||||
| mouse->handleMagnifyGesture (this, positionWithinPeer, time, scaleFactor); | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| void ComponentPeer::handlePaint (LowLevelGraphicsContext& contextToPaintTo) | void ComponentPeer::handlePaint (LowLevelGraphicsContext& contextToPaintTo) | ||||
| { | { | ||||
| @@ -315,6 +315,7 @@ public: | |||||
| //============================================================================== | //============================================================================== | ||||
| void handleMouseEvent (int touchIndex, const Point<int>& positionWithinPeer, const ModifierKeys& newMods, int64 time); | void handleMouseEvent (int touchIndex, const Point<int>& positionWithinPeer, const ModifierKeys& newMods, int64 time); | ||||
| void handleMouseWheel (int touchIndex, const Point<int>& positionWithinPeer, int64 time, const MouseWheelDetails&); | void handleMouseWheel (int touchIndex, const Point<int>& positionWithinPeer, int64 time, const MouseWheelDetails&); | ||||
| void handleMagnifyGesture (int touchIndex, const Point<int>& positionWithinPeer, int64 time, float scaleFactor); | |||||
| void handleUserClosingWindow(); | void handleUserClosingWindow(); | ||||