예제 #1
0
        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));
        }
예제 #2
0
        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
            });
        }
예제 #3
0
        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());
        }
예제 #4
0
        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());
        }
예제 #5
0
        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());
        }
예제 #6
0
파일: Util.cs 프로젝트: wiltonlazary/xwt
        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));
        }
예제 #7
0
        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
            });
        }
예제 #8
0
                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;
                        }
                    }
                }
예제 #9
0
        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));
        }
예제 #10
0
        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)));
            }
        }
예제 #11
0
        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);
        }
예제 #12
0
 public static NSPoint LocationInView(this NSEvent evnt, NSView view)
 {
     return view.ConvertPointFromView(evnt.LocationInWindow, null);
 }
예제 #13
0
 public static PointF GetEventLocation(this NSView view, NSEvent e)
 {
     return(LJD.Extensions.ToPointF(view.ConvertPointFromView(e.LocationInWindow, null)));
 }
예제 #14
0
        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);
        }