2

The following code draws a rectangle with NSBezierPath into an NSImage, which is then set as the image for an NSStatusItemButton.

import Cocoa

class ViewController: NSViewController {
    let statusItem: NSStatusItem = NSStatusBar.system.statusItem(
        withLength: NSStatusItem.squareLength)

    override func viewDidLoad() {
        super.viewDidLoad()

        let imageSize = NSSize.init(width: 18.0, height: 18.0)

        let statusItemImage = NSImage(
            size: imageSize,
            flipped: false,
            drawingHandler: { (dstRect: NSRect) -> Bool in
                NSColor.black.setStroke()

                let path = NSBezierPath()
                path.appendRect(NSRect(
                    x: NSMinX(dstRect),
                    y: NSMinY(dstRect),
                    width: 10,
                    height: 10))
                path.stroke()

                return true
        })

        statusItem.button?.image = statusItemImage
    }

    override var representedObject: Any? {
        didSet {
        }
    }
}

In the menu bar, it looks like this:

enter image description here

The left and bottom edge of the rectangle have a different width than the right and top edge.

How do I get a rectangle with equal line widths?

Johannes Bittner
  • 3,503
  • 2
  • 23
  • 21
  • Is your problem the drawing handler or image in nsstatusitem? Just my 2 cents cause you already got a correct answer for current question title. If I look at top right corner I see it doesn't allign to pixels (NSIntegralRect). – Marek H Nov 18 '19 at 09:40
  • My problem is that the lines of the rectangle do not have the same line widths in the menubar – Johannes Bittner Nov 21 '19 at 01:05
  • The proposed solution of user Sombre Osmo'z shows the same behaviour as my code. I missed adding that information in my last comment :) – Johannes Bittner Nov 26 '19 at 17:23
  • 1
    Again I need to repeat that you already have an answer for question title. Your problem is not with NSBezierPath. Correct question title is "How to disable image misalingment/scaling for nsstastusbarbutton image. To answer this question please look at the NSButton properties such as imageScaling. Alternatively try to disable NSStatusBarButton template image. – Marek H Nov 26 '19 at 18:12
  • Thanks, I assumed it's a problem with NSBezierPath. I updated the title. – Johannes Bittner Nov 26 '19 at 21:36

1 Answers1

0

You have to set a lineWidth for your path:

/// The new rectangle
let new = CGRect(origin: dstRect.origin,
                 size: .init(width: 10, height: 10))

let path = NSBezierPath(rect: new)
// The line width size 
path.lineWidth = 0.1

path.stroke()
Sombre Osmo'z
  • 165
  • 1
  • 8