     required init?(coder: NSCoder) {
         NSLog("init with coder")
         
-        self.curve = CubicBezier(p0: BKPoint(x: 100, y: 25),
-                                 p1: BKPoint(x: 10, y: 90),
-                                 p2: BKPoint(x: 110, y: 100),
-                                 p3: BKPoint(x: 150, y: 195))
+        self.draggables = [Draggable]()
 
         super.init(coder: coder)
+
+        self.cp0 = self.addDraggable(initialLocation: BKPoint(x: 100, y: 25), radius: 3)
+        self.cp1 = self.addDraggable(initialLocation: BKPoint(x: 10, y: 90), radius: 3)
+        self.cp2 = self.addDraggable(initialLocation: BKPoint(x: 110, y: 100), radius: 3)
+        self.cp3 = self.addDraggable(initialLocation: BKPoint(x: 150, y: 195), radius: 3)
+
+        self.updateCurves()
+
+    }
+    
+    func updateCurves() {
         
+        self.curve = CubicBezier(p0: cp0!.location,
+                                 p1: cp1!.location,
+                                 p2: cp2!.location,
+                                 p3: cp3!.location)
+
+        
+    }
+    
+    func draggable(_ draggable: Draggable, didUpdateLocation location: BKPoint) {
+        self.updateCurves()
+        self.resetCursorRects()
+        self.setNeedsDisplay(self.bounds)
+    }
+    
+    override func resetCursorRects() {
+        
+        let cursor: NSCursor = NSCursor.pointingHand()
+        
+        self.discardCursorRects()
+        for d: Draggable in self.draggables {
+            self.addCursorRect(d.cursorRect, cursor: cursor)
+        }
+    }
+    
+    func addDraggable(initialLocation location: BKPoint, radius: Double) -> Draggable {
+        let draggable = Draggable(initialLocation: location, radius: radius)
+        draggable.delegate = self
+        self.draggables.append(draggable)
+        return draggable
+    }
+    
+    override func mouseDown(with event: NSEvent) {
+        var location = self.convert(event.locationInWindow, to: self)
+        location.y = self.bounds.height - location.y
+        for d in self.draggables {
+            if d.containsLocation(location) {
+                self.selectedDraggable = d
+                return
+            }
+        }
+    }
+    
+    override func mouseDragged(with event: NSEvent) {
+        if let draggable : Draggable = self.selectedDraggable {
+            var location = self.convert(event.locationInWindow, to: self)
+            location.y = self.bounds.height - location.y
+            draggable.updateLocation(location)
+        }
+    }
+    
+    override func mouseUp(with event: NSEvent) {
+        self.selectedDraggable = nil
     }
     
     override func draw(_ dirtyRect: NSRect) {


import AppKit

class DemoView: NSView {
    
    var curve: CubicBezier
    
    override var isFlipped: Bool {
        get {
            return true

        context.setFillColor(NSColor.white.cgColor)
        context.fill(self.bounds)
        
        Draw.drawSkeleton(context, curve: curve!)
        Draw.drawCurve(context, curve: curve!)
        
    }
    
