NSImage, imageNamed and drawing ...

Hi,

I have created a method to get an NSImage according to the macoslib and I want to show for
instance the “NSImageNameStatusAvailable” icon/image in the window like the examples from macoslib
but I am unable to draw it correctly into the window - I always get a black rectangle.

However, the size and measurements are correctly drawn but no image with colors ect is shown. I know this since
switching from NSImageNameApplicationIcon to NSImageNameStatusAvailable results in different rectangles sizes
but still black. :frowning:

Not sure where the problem is but it think the drawing is wrong. I am not expert in MacOS programming
but I am learning steadily.

Could someone help ? Please do not post commercial addons ect.

Declare Function NSClassFromString Lib CocoaLib (aClassName As CFStringRef) As Ptr
Declare Function imageNamed Lib CocoaLib selector "imageNamed:" (class_id As Ptr, name As CFStringRef) As Ptr 
Dim iPtr As Ptr = imageNamed(NSClassFromString("NSImage"), "NStatusAvailable")
  If iPtr <> Nil Then
    Const NSCompositeSourceOver = 2
    Dim opacity As Double= 1.0
    Dim point As NSPoint
    Dim zeroRect As NSRect
    point.x = 50
    point.y = 50
    Declare Sub drawAtPoint Lib CocoaLib selector "drawAtPoint:fromRect:operation:fraction:" (obj_id As Ptr, point As NSPoint, fromRect As NSRect, op As Double, delta As Single)
    drawAtPoint(iPtr, point, zeroRect, NSCompositeSourceOver, CType(opacity, Single))
  End If

make that “op as integer” and it will work!

Oh, I almost forgot
NStatusAvailable should be NSStatusAvailable

Thanks Jim!!! Awesome.
I never had solved and found it myself.
You are right re the the name of the images (NSStatusAvailable.). That was only typo in the code quote.

Edit:
drawing the image in the window is fine but I actually wanted to draw it in a listbox/cell or a rectangle. How can I do this?

The code you have will draw into the current context, ie. g as graphics in a paint event. To draw into a picture you’ll need to use setCurrentContext… using the graphics object of a picture

[code]declare function graphicsContextWithGraphicsPort lib “Cocoa” selector _
“graphicsContextWithGraphicsPort:flipped:” (id as ptr,obj as ptr,flipped as Boolean) as ptr
declare sub setCurrentContext lib “Cocoa” selector “setCurrentContext:” (id As Ptr, obj As ptr)

dim p As new Picture(bounds.w,bounds.h)
dim cntx as ptr=ptr(p.Graphics.handle(Graphics.handletypecgcontextref))
//create an NSGraphicsContext from the CGGraphicsContext
dim nscntx As ptr =graphicsContextWithGraphicsPort(NSClassFromString(“NSGraphicsContext”),cntx,false)
//Set the NSGraphicsContext as the current drawing context
setCurrentContext(NSClassFromString(“NSGraphicsContext”),nscntx)
[/code]

then call the code you have to draw into the picture object.

I found a note in the macoslib project suggesting a way to convert the
NSImage to CGImage and then to XOJO picture. I did it with the declares CGImageForProposedRect
and CGContextDrawImage and so on and got it working but I was wondering to go through CG stuff.

Your proposal seems clearer to me.

Thanks again Jim!

I think it might be a better idea, if you’re only looking to get a Xojo picture object to draw elsewhere, to convert it MacOSLib’s way. The reason I used the above method was to capture pictures from controls that don’t have an NSImage, such as the window close button.

MacOSLib has a method
NSImage.MakePicture
and NSImage.LoadByName
So to simplify, you could call

myPicture=NSImage.LoadByName("NSStatusAvailable").MakePicture

Anyway, here’s a method to get a named image as a picture object. I tried to make it clear, so you can see what the declares do and how they work a little better.

[code]Function GetNamedPicture(name As String) As Picture
Declare Function NSClassFromString Lib CocoaLib (aClassName As CFStringRef) As Ptr
Declare Function imageNamed Lib CocoaLib selector “imageNamed:” (class_id As Ptr, name As CFStringRef) As Ptr

Dim iPtr As Ptr = imageNamed(NSClassFromString(“NSImage”), name) //get the NSImage

If iPtr <> Nil Then //we have an NSImage

declare function size lib CocoaLib selector "size" (obj_id as Ptr) as NSSize
dim s As NSSize=size(iPtr) //get the size of the NSImage

dim p as new picture(s.width,s.height)
dim cntx as Ptr=ptr(p.Graphics.Handle(Graphics.HandleTypeCGContextRef)) //get the graphics of the picture as CGContext

dim rect As NSRect
rect.rsize=s

declare function CGImageForProposedRect lib CocoaLib selector "CGImageForProposedRect:context:hints:" (obj_id as Ptr, byref proposedDestRect as NSRect, referenceContext as Ptr, hints as Ptr) as Ptr
dim cgPtr As ptr=CGImageForProposedRect(iPtr,rect,nil,nil) //convert the NSImage to CGImage

soft declare sub CGContextDrawImage lib CocoaLib (context as Ptr, rect as NSRect, image as Ptr)
CGContextDrawImage cntx, rect, cgPtr //Draw the CGImage to our Xojo picture

Return p

End If
End Function
[/code]

Also remembering the structures to define…

 NSPoint
             x as single
             y as single

NSRect
           origin as nspoint
           rsize as nssize

NSSize
            width as single
            height as single

appreciate your post and code snippet.:wink:
It’s similar what I’ve worked up according to the macoslib but it also good to know when
to set the context and drawtopoint if you don’t need a picture obj.

Additionally, thank you so much also for sharing your NSSearchField xojo project example.