From 2f04ceab98cb396ca0ddb4e0dcf3bdc44191487b Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Sat, 15 Sep 2018 19:08:33 +0100 Subject: [PATCH] add middle and right mouse button handling. --- src/Avalonia.Native.OSX/window.mm | 73 ++++++++++++++++++++++++--- src/Avalonia.Native/WindowImplBase.cs | 13 +++-- 2 files changed, 77 insertions(+), 9 deletions(-) diff --git a/src/Avalonia.Native.OSX/window.mm b/src/Avalonia.Native.OSX/window.mm index 93a3fcaec7..b94bc21e6d 100644 --- a/src/Avalonia.Native.OSX/window.mm +++ b/src/Avalonia.Native.OSX/window.mm @@ -82,6 +82,8 @@ protected: { ComPtr _parent; NSTrackingArea* _area; + bool _isLeftPressed, _isMiddlePressed, _isRightPressed, _isMouseOver; + NSEvent* _lastMouseDownEvent; } -(AvnView*) initWithParent: (WindowBaseImpl*) parent @@ -161,7 +163,7 @@ protected: return result; } -- (void)mouseMoved:(NSEvent *)event +- (void)mouseEvent:(NSEvent *)event withType:(AvnRawMouseEventType) type { auto localPoint = [self convertPoint:[event locationInWindow] toView:self]; auto avnPoint = [self toAvnPoint:localPoint]; @@ -172,10 +174,69 @@ protected: auto modifiers = [self getModifiers:[event modifierFlags]]; [self becomeFirstResponder]; - _parent->BaseEvents->RawMouseEvent(Move, timestamp, modifiers, point, delta); + _parent->BaseEvents->RawMouseEvent(type, timestamp, modifiers, point, delta); [super mouseMoved:event]; } +- (void)mouseMoved:(NSEvent *)event +{ + [self mouseEvent:event withType:Move]; +} + +- (void)mouseDown:(NSEvent *)event +{ + _isLeftPressed = true; + _lastMouseDownEvent = event; + [self mouseEvent:event withType:LeftButtonDown]; + _lastMouseDownEvent = nullptr; + + [super mouseDown:event]; +} + +- (void)otherMouseDown:(NSEvent *)event +{ + _isMiddlePressed = true; + _lastMouseDownEvent = event; + [self mouseEvent:event withType:MiddleButtonDown]; + _lastMouseDownEvent = nullptr; + + [super otherMouseDown:event]; +} + +- (void)rightMouseDown:(NSEvent *)event +{ + _isRightPressed = true; + _lastMouseDownEvent = event; + [self mouseEvent:event withType:RightButtonDown]; + _lastMouseDownEvent = nullptr; + + [super rightMouseDown:event]; +} + +- (void)mouseUp:(NSEvent *)event +{ + _isLeftPressed = false; + [self mouseEvent:event withType:LeftButtonUp]; + + [super mouseUp:event]; +} + +- (void)otherMouseUp:(NSEvent *)event +{ + _isMiddlePressed = false; + [self mouseEvent:event withType:MiddleButtonUp]; + + [super otherMouseUp:event]; +} + +- (void)rightMouseUp:(NSEvent *)event +{ + _isRightPressed = false; + [self mouseEvent:event withType:RightButtonUp]; + + [super rightMouseUp:event]; +} + - (AvnInputModifiers)getModifiers:(NSEventModifierFlags)mod { unsigned int rv = 0; @@ -189,12 +250,12 @@ protected: if (mod & NSEventModifierFlagCommand) rv |= Windows; - /*if (_isLeftPressed) - rv |= InputModifiers.LeftMouseButton; + if (_isLeftPressed) + rv |= LeftMouseButton; if (_isMiddlePressed) - rv |= InputModifiers.MiddleMouseButton; + rv |= MiddleMouseButton; if (_isRightPressed) - rv |= InputModifiers.RightMouseButton;*/ + rv |= RightMouseButton; return (AvnInputModifiers)rv; } diff --git a/src/Avalonia.Native/WindowImplBase.cs b/src/Avalonia.Native/WindowImplBase.cs index 277cbdc2c0..9b325b1016 100644 --- a/src/Avalonia.Native/WindowImplBase.cs +++ b/src/Avalonia.Native/WindowImplBase.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using Avalonia.Controls; using Avalonia.Controls.Platform.Surfaces; @@ -7,6 +7,7 @@ using Avalonia.Input.Raw; using Avalonia.Native.Interop; using Avalonia.Platform; using Avalonia.Rendering; +using Avalonia.Threading; namespace Avalonia.Native { @@ -76,11 +77,12 @@ namespace Avalonia.Native void IAvnWindowBaseEvents.Activated() => _parent.Activated?.Invoke(); - void IAvnWindowBaseEvents.Deactivated() => _parent.Deactivated?.Invoke(); void IAvnWindowBaseEvents.SoftwareDraw(IntPtr ptr, int stride, int pixelWidth, int pixelHeight, AvnSize logicalSize) { + Dispatcher.UIThread.RunJobs(DispatcherPriority.Render); + _parent._framebuffer = new SavedFramebuffer { Address = ptr, @@ -112,7 +114,11 @@ namespace Avalonia.Native { switch(type) { - case AvnRawMouseEventType.Move: + case AvnRawMouseEventType.LeaveWindow: + case AvnRawMouseEventType.Wheel: + break; + + default: Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1); Input?.Invoke(new RawMouseEventArgs(_mouse, timeStamp, _inputRoot, (RawMouseEventType)type, new Point(point.X, point.Y), (InputModifiers)modifiers)); break; @@ -126,6 +132,7 @@ namespace Avalonia.Native public IRenderer CreateRenderer(IRenderRoot root) { + //return new DeferredRenderer(root, AvaloniaLocator.Current.GetService()); return new ImmediateRenderer(root); }