Strange result when drawing icons into listbox with MacOSLib

1st of all please apologize: I am a total newbie on Xojo, who has not programmed for over 25 years and I am also not a native English speaker!

I want to write a program which should display some files from the Application folder with their icons and their filenames in a listbox.

Therefore I downloaded MacOSLib 2 (64 bit) from Github (from sergesd) and soon was successfully able to paint a files icon into a canvas object.

But when trying with the listbox it only paints the icon into the first column of the last visible row!

I am using the listbox CellBackgroundPaint Event and I can see it working in all visible cells, because before painting the icon it does a g.FillRect.

Why does g.Fillrect work in all the Cells an the following Command which draws the icon only in the firt column and last visible row?

That is the code within my CellbackgroundPaint Event:

if Icon <> nil then

 //set background color
  g.ForeColor = RGB(255, 0, 0, 229)
  g.FillRect 0, 0, g.Width, g.Height

  //draw icon
  Icon.Draw g, 0, 0
end if

I really appreciate any help on this. I have already spent hours fiddling around with no success so far.

Thank you very much.


Where did you tell Xojo you want it to draw the Icon in Row a, Cell b ?

I am not sure if I understood your question correct. But I thank you for stepping in …

In my sample code I have a window property named “Icon” of type MacIcon (a class defined in MacOSLib).

In the window open event I use the File Selection Dialog and after that pass the FolderItem to the MacIcon method NewIconFromFolderItem().

Here is the code in the Window Open Event:

dim dlg as new OpenDialog if dlg.ShowModal <> nil then Icon = MacIcon.NewIconFromFolderItem(dlg.Result) Listbox_Icon.Refresh end if

And then there is the code in the Listbox’s event Cellbackgroundpaint which I posted above.

Right now it’s just a quick test, so to my understanding the Icon should be painted in every cell.
As does the g.RectFill work in every cell.

But it does not!

Why not post a link to the sample project?

I would assume that the icons might have been painted, but then got out of scope and became nil, so then no longer get painted. Except for the last one which you still hold a reference to.


To be able to put something in Row 0, Cell (or Column) 1, you have to add one Row and to explicitely say so. Don’t you ?

// Add one Row and Text in Column 0 Listbox1.AddRow "This is column 0" Loc_Row = Listbox1.LastIndex // Get the # of the last added Row # Listbox1.Cell(Loc_Row,1) = "This is Column 1" // Text added in Column #1

For text (or string), that is what I meant. For drawings, I meant the same; something like (pseudo-code):

If Row = 1 And Cell = 2 Then // Put here code to draw the icon End If

Is it clear now ?

Also, Get an eye on the LR’s Refresh: it will say that this is deprecated, use Invalidate.

PS: what Xojo version are)you using (OS ?)

You are not returning True to cancel the standard BackgroundPaint behavior, so even if I wonder why the icon appears on the last row though maybe this will help?

I’ll try to keep this simple; drawing images via OS API in a listbox doesn’t work, the simplest route is to draw them to a Xojo Picture first, then draw that Xojo picture.

Alternatively, just think of the listbox as a canvas (which I actually believe it is), to which you can use OS API to draw images, however you must do the math yourself. Apple do system drawing, from the bottom-up (some would say the same as their current product line-up), where as Xojo does it’s top-down.

0, 0 is top left in Xojo, but is bottom left in macOS.

Well in the meantime I prepared my sample for uploading.

Everyone who wants to have a look will find it here:

@Sam: Since I am new, I will try to figure out what that means “draw to a Xojo Picture” and then “draw Xojo picture” into the listbox.

If someone can send me an example it would be very nice!

My goal ist to have an application list with icons and names.

Thx to all for contributing.

I am using XOJO 2018 Release 1 by the way.

Try this in the paint event

[code]If column = 0 Then
If Icon_Listbox <> Nil Then
Dim p As New Picture(g.Width, g.Height, 32)
Icon_Listbox.Draw p.Graphics, 0, 0

g.ForeColor = RGB(255, 0, 0, 229)
g.FillRect 0, 0, g.Width, g.Height
g.DrawPicture p, 0, 0

Return True

End If


Create a new Picture,
Draw the icon into that Picture
Draw that Picture into the Listbox.

I recommend:

When filling the listbox,

get the folderitem
get the icon
Create a new Picture,
Draw the icon into that Picture
Add a row to the listbox
set the rowtag(thelist.lastindex) = thepicture

And in the cellbackgroundpaint event, do something like this:

if row < me.listcount-1 and me.rowtag(row) <> nil then

//set background color
g.ForeColor = RGB(255, 0, 0, 229)
g.FillRect 0, 0, g.Width, g.Height

dim p as picture
p = me.rowtag(row)
g.drawpicture p, 0, 0

end if[/code]

That way you dont need to get the icon every time the cell refreshes

@Thomas Eckert : Thank you very much. That did it.

Also my thanks to all the other guys who were willing to help a humble amateur.

@Jeff Tullin: Thank you for the rowtag advice.