public override void MouseDown(NSEvent theEvent) { ColorRect oldSelectedItem = selectedItem; ColorRect thisRect; PointF mouseLoc = PointF.Empty; PointF mouseOffset = PointF.Empty; NSEventMask eventMask; bool dragged = false; bool timerOn = false; NSEvent autoScrollEvent = null; selectedItem = null; if (!Window.MakeFirstResponder(this)) { return; } mouseLoc = ConvertPointFromView(theEvent.LocationInWindow, null); // we go from last to first for (int x = rects.Count - 1; x >= 0; x--) { thisRect = rects[x]; if (IsMouseInRect(mouseLoc, thisRect.Frame)) { selectedItem = thisRect; break; } } if (oldSelectedItem != selectedItem) { if (oldSelectedItem != null) { SetNeedsDisplayInRect(oldSelectedItem.Frame); } if (selectedItem != null) { SetNeedsDisplayInRect(selectedItem.Frame); } updateRulers(); } if (selectedItem == null || selectedItem.IsLocked) { return; } mouseOffset.X = mouseLoc.X - selectedItem.Frame.Location.X; mouseOffset.Y = mouseLoc.Y - selectedItem.Frame.Location.Y; eventMask = NSEventMask.LeftMouseDragged | NSEventMask.LeftMouseUp | NSEventMask.Periodic; while (theEvent != null) { RectangleF visibleRect = VisibleRect(); switch (theEvent.Type) { case NSEventType.Periodic: if (autoScrollEvent != null) { Autoscroll(autoScrollEvent); } moveSelectedItemWithEvent(autoScrollEvent, mouseOffset); break; case NSEventType.LeftMouseDragged: if (!dragged) { drawRulerLinesWithRect(selectedItem.Frame); } dragged = true; mouseLoc = ConvertPointFromView(theEvent.LocationInWindow, null); moveSelectedItemWithEvent(theEvent, mouseOffset); if (!IsMouseInRect(mouseLoc, visibleRect)) { if (!timerOn) { NSEvent.StartPeriodicEventsAfterDelay(0.1, 0.1); timerOn = true; } autoScrollEvent = theEvent; break; } else { if (timerOn) { NSEvent.StopPeriodicEvents(); timerOn = false; autoScrollEvent = null; } } DisplayIfNeeded(); break; case NSEventType.LeftMouseUp: if (timerOn) { NSEvent.StopPeriodicEvents(); timerOn = false; autoScrollEvent = null; } if (dragged) { eraseRulerLinesWithRect(selectedItem.Frame); } updateRulers(); return; default: break; } theEvent = this.Window.NextEventMatchingMask(eventMask); } }