Draw a line on an NSWINDOW

Given X1,Y1, X2,Y2 that define the end points of a line
Draw said line on an NSWindow

  • Note : to the best of my knowlege you cannot draw a line DIRECTLY to the NSWindow, it must be draw within a NSView that is added to the window
  • so first the supplied coordinates must be converted to define a NSView
  • Then those must be further converted to be two points WITHIN the NSView

yep

the width would be max(x1, x2) - min(x1,x2)
height much the same

then offset the navies to the left = min(x1,x2) top = min(y1,y2)

then draw with the points internally offset y the left & top of the NSView

been there done this

Thanks… I arrived at basically the same answer :slight_smile:

figured you might

now draw a line inside and nsview that is inside another nsview :stuck_out_tongue:
it gets messy quickly but I suspect Swift has better facilities for dealing with the true location of such an deeply nested embedded view

in old version you can draw in nswindow now it’s forbidden

func drawLineOnWindow(_ window: NSWindow) {
guard let context = window.graphicsContext?.cgContext else {
print(“Failed to get CGContext”)
return
}

    // Begin drawing
    context.saveGState()
    
    context.setStrokeColor(NSColor.red.cgColor)
    context.setLineWidth(2.0)
    
    // Draw a line from (50, 50) to (350, 250)
    context.move(to: CGPoint(x: 50, y: 50))
    context.addLine(to: CGPoint(x: 350, y: 250))
    
    context.strokePath()
    context.restoreGState()
}

yeah that doesn’t work, and even if it did, it would not be applicable to this app, seeing as the coordiantes are not know until runtime, plus I need to have complete control of the z-order, where this method would draw the line(s) under everthing else on the window, but thanks

here is my solution… seems to work in all use cases :slight_smile:

open class uxLINE: ux$Shape {
    var pt1 = CGPoint.zero
    var pt2 = CGPoint.zero
    @MainActor required public init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    public override init(frame:CGRect=CGRect.zero) {
        let oldFrame = frame
        super.init(frame:CGRect(x:0,y:0,width:max(frame.origin.x,frame.size.width),height:max(frame.origin.y,frame.size.height)))
        pt1 = oldFrame.origin
        pt2 = CGPoint(x:oldFrame.size.width,y:oldFrame.size.height)
        constructor()
    }

  // MARK: OBJECT DECLARATION
    public override func draw(_ rect: CGRect) {
        // unlike other shapes, LINE uses CGRECT to store the line ENDS
        super.draw(rect)
        let context: CGContext = NSGraphicsContext.current!.cgContext
        context.setStrokeColor(lineColor.cgColor)
        context.setLineWidth(borderWidth)
        context.setLineDash(phase: 0,lengths: penStyle.mask)
        context.move(to: pt1)
        context.addLine(to: pt2)
        context.strokePath()
    }
}
2 Likes