swiftmacoscore-graphicscgpointnsevent

Move four Rectangle's points simultaneously


I'm developing a macOS app that generates rectangles. I can separately move rectangles' points with left mouse button LMB. The principle of operation: when I drag 1 point with a LMB, the other 3 points will follow it at the same time with the same offset.

How can I move all four points of a rectangle simultaneously?

enter image description here

The code for constructing elements:

enum RectPoint {
    case point1(point: CGPoint)
    case point2(point: CGPoint)
    case point3(point: CGPoint)
    case point4(point: CGPoint)
 
    func pointCoord() -> [CGPoint] {    
        switch self {  
            case .point1(let point): return [point]
            case .point2(let point): return [point]
            case .point3(let point): return [point]
            case .point4(let point): return [point]
        }
    }
}
class SpecialView: NSView {
    var array: [RectPoint] = [] 
    private var trackVertex: RectPoint?
    private var trackVertexIndex: Int?
    private var trackElementIndex: Int?

    private func updateDragging(point: CGPoint) {
        guard let trackVertex = self.trackVertex,
              let trackVertexIndex = self.trackVertexIndex,
              let trackElementIndex = self.trackElementIndex   
        else { return }
  
        let newVertex = trackVertex.debugReleaseChecking(point, 
                                    atElementIndex: trackElementIndex)
        array[trackVertexIndex] = newVertex     
        self.needsDisplay = true
    }
}

Here's a method for dragging points:

func mouseDragged(event: NSEvent) {        
   var point = self.convertPoint(event.locationInWindow, fromView: nil)
   updateDragging(point) 
}

Solution

  • Basically, you need to calculate the offset that is being applied to the tracked point and apply that offset to all the other points. It's easiest to do this by separating the calculation and the update, so the update always runs on all points.

    To calculate the offset just subtract the current point x and y from the new point x and y.

    Something along the lines of:

    func mouseDragged(event: NSEvent) {
        let eventPoint = self.convertPoint(event.locationInWindow, fromView: nil)
        let trackingPoint = XXX
    
        let xOffset = eventPoint.x - trackingPoint.x
        let yOffset = eventPoint.y - trackingPoint.y
    
        for point in allPoints {
            point.x += xOffset
            point.y += yOffset
        }
    }