Search code examples
objective-crubymacoscocoarubymotion

How to implement image button on OSX in RubyMotion?


This strikes me as something that should be incredibly easy, but I just can't get it to work.

I'm creating a button as such:

closeButton = NSButton.alloc.initWithFrame(
    [[10, 10], [100, 22]]
  ).tap do |button|
    button.bezelStyle = NSShadowlessSquareBezelStyle
    button.buttonType = NSMomentaryChangeButton
    button.title = 'Close'
    button.bordered = false
    button.image = NSImage.imageNamed('img/circle')
    p button.image
    button.imagePosition = NSImageOnly
    button.target = window
    button.action = 'close'
  end

There are 2 images, circle.png and circle@2x.png, stored in /Resources/img.

Needless to say, I get a gray button with no text or image within it. Also, p button.image returns nil.

I've cleaned and rebuilt my project a number of times.

This doesn't seem like it should be so difficult to implement. What am I overlooking?


Solution

  • So I sort of figured this out. It would appear that either imageNamed doesn't work the way I'm expecting, or I'm simply using it incorrectly.

    I was able to set an image on a button by doing the following:

    NSButton.alloc.initWithFrame(
        [[110, 10], [100, 22]]
    ).tap do |button|
        neutralImgPath = NSBundle.mainBundle.pathForResource("img/circle2", ofType: "png")
        neutralImgUrl = NSURL.fileURLWithPath(neutralImgPath)
        neutralImg = NSImage.alloc.initWithContentsOfURL(neutralImgUrl)
    
        button.setImage(neutralImg)
    
        button.setImageScaling(NSImageScaleProportionallyDown)
        button.setImagePosition(NSImageOnly)
    
        button.translatesAutoresizingMaskIntoConstraints = false
        button.bordered = false
        button.bezelStyle = NSShadowlessSquareBezelStyle
        button.buttonType = NSMomentaryChangeButton
    
        button.target = MainAppWindow.get
        button.action = 'minimize:'
    end
    

    Would definitely love to figure out a more concise way to do this, but for now, it gets the job done!