public static NSEvent TransformLocationOfEvent(NSView view, NSEvent nsEvent) { if (!IsMouseEvent(nsEvent.Type)) { return(nsEvent); } var newLocation = view.ConvertPointFromView(nsEvent.LocationInWindow, null); if (IsMouseEnterExitEvent(nsEvent.Type)) { return(CreateMouseEnterExitEvent(nsEvent, newLocation)); } return(NSEvent.MouseEvent( nsEvent.Type, newLocation, nsEvent.ModifierFlags, nsEvent.Timestamp, nsEvent.WindowNumber, null, nsEvent.EventNumber, nsEvent.ClickCount, nsEvent.Pressure)); }
internal MSG TranslateMouseCore(NSEvent e, out bool client) { var clientView = view as IClientView; var nspoint = view.ConvertPointFromView(e.LocationInWindow, null); var localMonoPoint = driver.NativeToMonoFramed(nspoint, view); var clientRect = clientView.ClientBounds.ToRectangle(); if ((clientView != null && clientRect.Contains(localMonoPoint)) || driver.Grab.Hwnd != IntPtr.Zero) { client = true; localMonoPoint.Offset(-clientRect.X, -clientRect.Y); } else { client = false; } return(new MSG { hwnd = view.Handle, lParam = (IntPtr)(localMonoPoint.Y << 16 | (localMonoPoint.X & 0xFFFF)), pt = e.Window == null ? driver.NativeToMonoScreen(NSEvent.CurrentMouseLocation).ToPOINT() : driver.NativeToMonoScreen(e.Window.ConvertBaseToScreen(e.LocationInWindow)).ToPOINT(), refobject = view }); }
internal virtual NSDraggingItem[] CreateDraggingItems(NSView view, object data) { var items = new List <NSDraggingItem>(); DraggedData = (data is IDataObject) ? data : new DataObject(data); if (data is IDataObject idata) { if (idata.GetDataPresent(CFSTR_FILEDESCRIPTORW)) { foreach (var promise in CreateFilePromises(idata)) { items.Add(new NSDraggingItem(promise.AsPasteboardWriting())); } } } if (data is String text) { var pbitem = NewPasteboardItem(); pbitem.SetStringForType(text, UTTypeUTF8PlainText); var item = new NSDraggingItem(pbitem.AsPasteboardWriting()); items.Add(item); } if (items.Count == 0) { var pbitem = NewPasteboardItem(); var item = new NSDraggingItem(pbitem.AsPasteboardWriting()); items.Add(item); } var location = view.ConvertPointFromView(LastMouseDown.LocationInWindow, null); var maxSize = new CGSize(320, 240); var snapshot = TakeSnapshot(view, data); if (snapshot != null) { var size = ScaleToFit(snapshot.Size, maxSize); var bounds = new CGRect(location.Move(-8, -8), size); int i = 0; foreach (var item in items) { if (i++ == 0) { item.SetDraggingFrame(bounds, snapshot); } else { item.DraggingFrame = bounds; } } } return(items.ToArray()); }
public static PointF GetLocation(NSView view, NSEvent theEvent) { var loc = view.ConvertPointFromView(theEvent.LocationInWindow, null); if (!view.IsFlipped) { loc.Y = view.Frame.Height - loc.Y; } return(loc.ToEto()); }
public static PointF ToEto(this CGPoint locationInWindow, NSView view) { var loc = view.ConvertPointFromView(locationInWindow, null); if (!view.IsFlipped) { loc.Y = view.Frame.Height - loc.Y; } return(loc.ToEto()); }
public static CGPoint ConvertPointFromEvent(this NSView view, NSEvent theEvent) { var point = theEvent.LocationInWindow; if (view.Window != null && theEvent.WindowNumber != view.Window.WindowNumber) { point = theEvent.Window.ConvertBaseToScreen(point); point = view.Window.ConvertScreenToBase(point); } return(view.ConvertPointFromView(point, null)); }
internal MSG TranslateMouseCore(NSEvent e, out bool isClient, NSView target = null) { var window = e.Window; var locationInWindow = e.LocationInWindow; if (target != null && target.Window != null) { locationInWindow = target.Window.ConvertPointFromWindow(locationInWindow, window); window = target.Window; } else { target = view; } var nspoint = target.ConvertPointFromView(locationInWindow, null); var localMonoPoint = driver.NativeToMonoFramed(nspoint, target); isClient = false; if (target is IClientView client) { var clientRect = client.ClientBounds.ToRectangle(); if (clientRect.Contains(localMonoPoint) || driver.Grab.Hwnd != IntPtr.Zero) { isClient = true; localMonoPoint.Offset(-clientRect.X, -clientRect.Y); } } else { if (!(target is MonoView)) { isClient = true; } } return(new MSG { hwnd = target.Handle, lParam = (IntPtr)(localMonoPoint.Y << 16 | (localMonoPoint.X & 0xFFFF)), pt = window == null ? driver.NativeToMonoScreen(NSEvent.CurrentMouseLocation).ToPOINT() : driver.NativeToMonoScreen(window.ConvertPointToScreenSafe(locationInWindow)).ToPOINT(), refobject = target }); }
public override void MouseEntered(NSEvent evt, CGRect frame, NSView view) { base.MouseEntered(evt, frame, view); if (view is PathSelectorView selector) { var locationInView = view.ConvertPointFromView(evt.LocationInWindow, null); var cellIdx = selector.IndexOfCellAtX(locationInView.X); if (cellIdx == -1 || cellIdx > selector.Cells.Length - 1) { selector.ToolTip = string.Empty; } else { var item = selector.Cells [cellIdx]; selector.ToolTip = item?.ToolTip ?? string.Empty; } } }
public override NSCellHit HitTest(NSEvent forEvent, RectangleF inRect, NSView ofView) { PointF point = ofView.ConvertPointFromView(forEvent.LocationInWindow, null); if (_image != null) { RectangleF imageFrame; inRect.Divide(3 + _image.Size.Width, CGRectEdge.MinXEdge, out imageFrame, out inRect); imageFrame.X += 3; imageFrame.Size = _image.Size; if (ofView.MouseinRect(point, imageFrame)) { return(NSCellHit.ContentArea); } } return(base.HitTest(forEvent, inRect, ofView)); }
Optional <Point <Points> > ToPoint(CGPoint screenPoint) { var window = _originView.Window; if (window == null) { // The view isn't in any window, so there's nothing sensible to return. return(Optional.None()); } var windowPoint = window.ConvertRectFromScreen(new CGRect(screenPoint, new CGSize(0, 0))).Location; if (_space == Space.Local) { var localPointCocoa = _originView.ConvertPointFromView(windowPoint, null); return(Point.Create <Points>((double)localPointCocoa.X, (double)(_originView.Frame.Height - localPointCocoa.Y))); } else { return(Point.Create <Points>((double)windowPoint.X, (double)(window.Frame.Height - windowPoint.Y))); } }
void TranslateMouseEvent(NSEvent e) { var clientView = view as IClientView; CGPoint nspoint = e.LocationInWindow; Point localMonoPoint; bool client = clientView == null; nspoint = view.ConvertPointFromView(nspoint, null); localMonoPoint = driver.NativeToMonoFramed(nspoint, view); if ((clientView != null && clientView.ClientBounds.ToRectangle().Contains(localMonoPoint)) || driver.Grab.Hwnd != IntPtr.Zero) { client = true; localMonoPoint.X -= (int)clientView.ClientBounds.X; localMonoPoint.Y -= (int)clientView.ClientBounds.Y; } int button = (int)e.ButtonNumber; if (button >= (int)NSMouseButtons.Excessive) { button = (int)NSMouseButtons.X; } else if (button == (int)NSMouseButtons.Left && ((driver.ModifierKeys & Keys.Control) != 0)) { button = (int)NSMouseButtons.Right; } int msgOffset4Button = 3 * (button - (int)NSMouseButtons.Left); if (button >= (int)NSMouseButtons.X) { ++msgOffset4Button; } MSG msg = new MSG(); msg.hwnd = view.Handle; msg.lParam = (IntPtr)(localMonoPoint.Y << 16 | (localMonoPoint.X & 0xFFFF)); if (e.Window == null) { msg.pt = driver.NativeToMonoScreen(NSEvent.CurrentMouseLocation).ToPOINT(); } else { msg.pt = driver.NativeToMonoScreen(e.Window.ConvertBaseToScreen(e.LocationInWindow)).ToPOINT(); } msg.refobject = view; switch (e.Type) { case NSEventType.LeftMouseDown: case NSEventType.RightMouseDown: case NSEventType.OtherMouseDown: // FIXME: Should be elsewhere if (e.ClickCount > 1) { msg.message = (client ? Msg.WM_LBUTTONDBLCLK : Msg.WM_NCLBUTTONDBLCLK) + msgOffset4Button; } else { msg.message = (client ? Msg.WM_LBUTTONDOWN : Msg.WM_NCLBUTTONDOWN) + msgOffset4Button; } msg.wParam = (IntPtr)(ModifiersToWParam(e.ModifierFlags) | ButtonNumberToWParam(e.ButtonNumber)); break; case NSEventType.LeftMouseUp: case NSEventType.RightMouseUp: case NSEventType.OtherMouseUp: msg.message = (client ? Msg.WM_LBUTTONUP : Msg.WM_NCLBUTTONUP) + msgOffset4Button; msg.wParam = (IntPtr)(ModifiersToWParam(e.ModifierFlags) | ButtonNumberToWParam(e.ButtonNumber)); break; case NSEventType.MouseMoved: case NSEventType.LeftMouseDragged: case NSEventType.RightMouseDragged: case NSEventType.OtherMouseDragged: msg.wParam = (IntPtr)(ModifiersToWParam(e.ModifierFlags) | ButtonMaskToWParam(NSEvent.CurrentPressedMouseButtons)); msg.message = (client ? Msg.WM_MOUSEMOVE : Msg.WM_NCMOUSEMOVE); break; case NSEventType.ScrollWheel: bool horizontal = e.ScrollingDeltaY == 0 && e.ScrollingDeltaX != 0; int delta = ScaleAndQuantizeDelta((float)(horizontal ? e.ScrollingDeltaX : e.ScrollingDeltaY), e.HasPreciseScrollingDeltas); if (delta == 0) { return; } if (e.Phase == NSEventPhase.None && e.MomentumPhase == NSEventPhase.None || e.Phase == NSEventPhase.Changed || e.MomentumPhase == NSEventPhase.Changed) { msg.message = Msg.WM_MOUSEWHEEL; msg.wParam = (IntPtr)(ModifiersToWParam(e.ModifierFlags) | ButtonMaskToWParam(NSEvent.CurrentPressedMouseButtons)); msg.wParam = (IntPtr)(((int)msg.wParam & 0xFFFF) | (delta << 16)); msg.lParam = (IntPtr)((msg.pt.x & 0xFFFF) | (msg.pt.y << 16)); break; } return; case NSEventType.MouseEntered: if (e.TrackingArea?.Owner is NSView entered) { msg.hwnd = entered.Handle; msg.wParam = (IntPtr)(ModifiersToWParam(e.ModifierFlags) | ButtonMaskToWParam(NSEvent.CurrentPressedMouseButtons)); msg.message = Msg.WM_MOUSE_ENTER; Application.SendMessage(ref msg); return; } break; case NSEventType.MouseExited: if (e.TrackingArea?.Owner is NSView exited) { msg.hwnd = exited.Handle; msg.wParam = (IntPtr)(ModifiersToWParam(e.ModifierFlags) | ButtonMaskToWParam(NSEvent.CurrentPressedMouseButtons)); msg.message = Msg.WM_MOUSELEAVE; Application.SendMessage(ref msg); return; } break; //case NSEventType.TabletPoint: //case NSEventType.TabletProximity: default: return; } Application.SendMessage(ref msg); }
public static NSPoint LocationInView(this NSEvent evnt, NSView view) { return view.ConvertPointFromView(evnt.LocationInWindow, null); }
public static PointF GetEventLocation(this NSView view, NSEvent e) { return(LJD.Extensions.ToPointF(view.ConvertPointFromView(e.LocationInWindow, null))); }
void TranslateMouseEvent(NSEvent e) { var clientView = view as IClientView; bool client = clientView == null; var nspoint = view.ConvertPointFromView(e.LocationInWindow, null); var localMonoPoint = driver.NativeToMonoFramed(nspoint, view); if ((clientView != null && clientView.ClientBounds.ToRectangle().Contains(localMonoPoint)) || driver.Grab.Hwnd != IntPtr.Zero) { client = true; localMonoPoint.X -= (int)clientView.ClientBounds.X; localMonoPoint.Y -= (int)clientView.ClientBounds.Y; } MSG msg = new MSG(); msg.hwnd = view.Handle; msg.lParam = (IntPtr)(localMonoPoint.Y << 16 | (localMonoPoint.X & 0xFFFF)); if (e.Window == null) { msg.pt = driver.NativeToMonoScreen(NSEvent.CurrentMouseLocation).ToPOINT(); } else { msg.pt = driver.NativeToMonoScreen(e.Window.ConvertBaseToScreen(e.LocationInWindow)).ToPOINT(); } msg.refobject = view; switch (e.Type) { case NSEventType.LeftMouseDown: case NSEventType.RightMouseDown: case NSEventType.OtherMouseDown: // FIXME: Should be elsewhere if (e.ClickCount > 1) { msg.message = (client ? Msg.WM_LBUTTONDBLCLK : Msg.WM_NCLBUTTONDBLCLK) + MsgOffset4Button(e); } else { msg.message = (client ? Msg.WM_LBUTTONDOWN : Msg.WM_NCLBUTTONDOWN) + MsgOffset4Button(e); } msg.wParam = (IntPtr)(e.ModifiersToWParam() | e.ButtonNumberToWParam()); break; case NSEventType.LeftMouseUp: case NSEventType.RightMouseUp: case NSEventType.OtherMouseUp: msg.message = (client ? Msg.WM_LBUTTONUP : Msg.WM_NCLBUTTONUP) + MsgOffset4Button(e); msg.wParam = (IntPtr)(e.ModifierFlags.ToWParam() | e.ButtonNumberToWParam()); break; case NSEventType.MouseMoved: msg.wParam = (IntPtr)(e.ModifierFlags.ToWParam()); msg.message = (client ? Msg.WM_MOUSEMOVE : Msg.WM_NCMOUSEMOVE); break; case NSEventType.LeftMouseDragged: msg.wParam = (IntPtr)(e.ModifierFlags.ToWParam() | (uint)MsgButtons.MK_LBUTTON); msg.message = (client ? Msg.WM_MOUSEMOVE : Msg.WM_NCMOUSEMOVE); break; case NSEventType.RightMouseDragged: msg.wParam = (IntPtr)(e.ModifierFlags.ToWParam() | (uint)MsgButtons.MK_RBUTTON); msg.message = (client ? Msg.WM_MOUSEMOVE : Msg.WM_NCMOUSEMOVE); break; case NSEventType.OtherMouseDragged: msg.wParam = (IntPtr)(e.ModifierFlags.ToWParam() | (uint)MsgButtons.MK_MBUTTON); msg.message = (client ? Msg.WM_MOUSEMOVE : Msg.WM_NCMOUSEMOVE); break; case NSEventType.ScrollWheel: bool horizontal = e.ScrollingDeltaY == 0 && e.ScrollingDeltaX != 0; int delta = ScaleAndQuantizeDelta((float)(horizontal ? e.ScrollingDeltaX : e.ScrollingDeltaY), e.HasPreciseScrollingDeltas); if (delta == 0) { return; } if (e.Phase == NSEventPhase.None && e.MomentumPhase == NSEventPhase.None || e.Phase == NSEventPhase.Changed || e.MomentumPhase == NSEventPhase.Changed) { msg.message = Msg.WM_MOUSEWHEEL; msg.wParam = (IntPtr)(e.ModifiersToWParam()); msg.wParam = (IntPtr)(((int)msg.wParam & 0xFFFF) | (delta << 16)); msg.lParam = (IntPtr)((msg.pt.x & 0xFFFF) | (msg.pt.y << 16)); break; } return; case NSEventType.MouseEntered: case NSEventType.MouseExited: // We use overlapping track rectanges on every control, so the Entered/Exited events // are sent not only to the top-level visible view, but also to its superviews. // This has to be converted to the the model where only the top-level control receives // the messages. // // The conversion is by performing the hit test. Note that e.LocationInWindow is NOT // updated by the time the tracking events are received and thus e.Window. // MouseLocationOutsideOfEventStream has to be used instead. // // The Exited event has to be handled the same way as the entered event to cover the // following scenario: // ___________________________ // | Panel | // | ______________ | // | | Button | | // // When you move the mouse over the Button you will receive the Entered event for // it. At the same time the Panel already had Entered called for its own tracking area. // Now moving the mouse away from the Button into the Panel area will cause an // Exited event on the Button's tracking rectangle, but it will NOT generate any // Entered event. In the System.Windows.Forms world we want to receive WM_MOUSELEAVE // on the Button and WM_MOUSE_ENTERED on the Panel. // // Further reading: // https://stackoverflow.com/questions/9986267/mouse-enter-exit-events-on-partially-hidden-nsviews var newMouseView = e.Window?.ContentView.HitTest(e.LocationInWindow) ?? e.Window?.ContentView.Superview?.HitTest(e.LocationInWindow); var newMouseViewHandle = newMouseView is MonoView ? newMouseView.Handle : IntPtr.Zero; #if DEBUG_MOUSE_ENTER_EXIT { // DEBUG Console.Write(e.Type == NSEventType.MouseEntered ? "ENTER " : "EXIT "); if (newMouseView != null) { Console.Write("NEW: " + DebugUtility.ControlInfo(newMouseView)); } else { Console.Write("NO NEW"); } } #endif if (newMouseViewHandle == driver.LastEnteredHwnd) { return; } // Keep track of the last entered window during grab, but don't send messages. The // messages are sent by XplatUICocoa.GrabWindow and XplatUICocoa.UngrabWindow when // the grabbing state is entered/exited. if (driver.Grab.Hwnd != IntPtr.Zero) { driver.LastEnteredHwnd = newMouseViewHandle; return; } msg.wParam = (IntPtr)(e.ModifiersToWParam() | Mac.Extensions.ButtonMaskToWParam(NSEvent.CurrentPressedMouseButtons)); // First notify the old window that mouse left it if (driver.LastEnteredHwnd != IntPtr.Zero) { msg.hwnd = driver.LastEnteredHwnd; msg.message = Msg.WM_MOUSELEAVE; driver.LastEnteredHwnd = IntPtr.Zero; Application.SendMessage(ref msg); } // And then notify the new window that mouse entered it if (newMouseViewHandle != IntPtr.Zero) { msg.hwnd = newMouseViewHandle; msg.message = Msg.WM_MOUSE_ENTER; driver.LastEnteredHwnd = newMouseViewHandle; Application.SendMessage(ref msg); } return; //case NSEventType.TabletPoint: //case NSEventType.TabletProximity: default: return; } Application.SendMessage(ref msg); }