Listbox Custom Select Color Descenders

OS X 10.11.4
Xojo 2016r1.1

This is, I guess, a bug which I have submitted, but I wonder someone has noticed this and found a work around.

If I choose a custom color for the text of a selected row of a listbox, the bottom of letters with descenders is visible at the top of the row.

Default Color: No problem

Custom Color (Yellow): Note how the lower part of the “g” in lungs appears at the top of the row.

What’s the bug report number?
Does the issue present itself when retina capabilities are disabled?

Thanks Parnell.

You jogged me to find the workaround, or more accurately, avoid the problem all together.

I found some code on the Forum

If row = Me.ListIndex Then g.ForeColor = RGB(256,256,0) g.DrawString(Me.Cell(row, column), 0, 0) End If

in a discussion of changing the color of the text of the selected row of a listbox. I just copied it into the CellTextPaint Event of my listbox.

The actual bug is not related to the line g.ForeColor = RGB(256,256,0) (which was my assumption)

Rather it is related to the accompanying line g.DrawString(Me.Cell(row, column), 0, 0)

Reexamining my own situation, I found that the line g.DrawString(Me.Cell(row, column), 0, 0) is actually entirely unnecessary. I am not sure why the contributor of this code was employing this line. Perhaps his own context was different.

If I get rid of this line g.DrawString(Me.Cell(row, column), 0, 0) then the problem goes away.


Bug Report Number: 43715 (I have amended it to reflect the above)

It does not affected by having retina capabilities turned off.

That’s the problem with forum code. It is often just dashed out without much thought, let alone testing. There’s no way that code would ever produce correct results.

For the sake of completeness, IF you wanted to draw the text yourself, the correct code would be

If row = Me.ListIndex Then
    g.ForeColor = RGB(256,256,0)
    g.DrawString(Me.Cell(row, column), X, Y)
    return True
End If

Note the use of the X and Y values passed into CellTextPaint, and the return statement.

According to Robert’s post, you don’t even need to draw the string just change the forecolor.
Curious as to which is the tested answer.

To be extra complete, I was using the Drawstring method until I decided to support Retina. Instead of drawing in the cell background, I now simply return false after changing the g.TextFont and let the system draw the font itself at full resolution.

Both work, hence the capitalized IF in my post. If you draw it yourself, you should return True to tell the listbox not to draw it as well. If you just set the graphics properties and return False, the listbox will draw the text for you using those properties. What Robert was seeing was the result of the text being drawn twice, once by his code at (0,0) and once by the listbox itself (because he wasn’t returning True).

The Y position of DrawString is the baseline of the text. Drawing at (0,0) means that the text above the baseline is drawn off the graphics area (above Y=0), while the descenders are drawn at the top of the graphics region. You can see that clearly in his second image.

Both work, but to have full Retina support at 144dpi requires more than simply g.drawString.

May be I’m off the mark, but instead of: “If row = Me.ListIndex then…” I would use: “if me.selected(row) then…” to take care of all selected rows. Of course, if no text changing is expected.