I’m drawing an image with alpha channel to one of my listbox columns. Unfortunately this has the result of that cell becoming discolored when the row is selected.
In my PaintCellBackground I need to do g.FillRectangle with the color of the selection prior to drawing my Picture, however I am having a hard time finding that color value.
I’ve tried Color.HighlightColor and it’s close, but it’s a bit off. How can I calculate the exact system color of a selected row?
I need something that works on both Mac & Windows.
@Emile_Schwarz To be honest, I haven’t tested Windows yet. I’m having a hard time getting any Xojo apps to run in Windows at the moment, even in the debugger, Process just terminates a moment after launching. I will probably need to set up a new Windows environment to test in.
@Greg_O Thanks for this! Unfortunately it still seems to be a bit off:
Oh definitely, I have tested regularly up until this update in the software on Windows. But something seems to have broken and Xojo apps, compiled or debugged, will no longer run despite not having changed anything on the Windows PC, not even an update. Strangely enough the Xojo IDE still runs. But none of my compiled apps will work.
Public Function ListboxHighlightColor() As Color
var c as Color
#If TargetWindows Then
c = Color.HighlightColor
#Elseif TargetMacOS
If System.Version >= "10.14" Then
c = ColorGroup.NamedColor("selectedContentBackgroundColor")
Else
c = ColorGroup.NamedColor("selectedControlColor")
End If
#EndIf
return c
End Function
Weird. I used to have Sam’s app but lost it when I repaved my Macs a while ago and then couldn’t re-download it from the Canadian store, but this link took me to the US store which worked, yeah!
I discovered that Color.HighlightColor is incorrect on Windows when it is in dark mode. Instead, you should use Color.LightBevelColor.
So here is the revised solution:
Public Function ListboxHighlightColor() As Color
var c as Color
#If TargetWindows Then
c = if(Color.IsDarkMode, Color.LightBevelColor, Color.HighlightColor)
#Elseif TargetMacOS
c = if(System.Version >= "10.14", ColorGroup.NamedColor("selectedContentBackgroundColor"), _
ColorGroup.NamedColor("selectedControlColor"))
#EndIf
return c
End Function
Here is my code to draw these images in the field, the ListboxHighlightColor() method is employed to draw the background color if the row is selected and the PopularityBar(idx) is a method elsewhere in my code that returns the appropriate picture object based on the percentage. The key is in the constructor for the new Picture object when you’re resizing it to fit the cell that you don’t specify a bit depth, that preserves the alpha channel and lets you draw your image onto transparent.
Dim originalPicture As Picture = PopularityBar(idx)
If originalPicture <> Nil Then
// First, fill the background if the row is selected
If Me.RowSelectedAt(row) Then
g.DrawingColor = ListboxHighlightColor()
g.FillRectangle(0, 0, g.Width, g.Height)
End If
// Define the factors for the target size as a percentage of the cell dimensions
var heightFactor As Double = 0.75 // 75% of the cell height
var widthFactor As Double = 0.50 // 50% of the cell width
// Calculate the maximum allowed dimensions based on the factors
var maxAllowedHeight As Integer = g.Height * heightFactor
var maxAllowedWidth As Integer = g.Width * widthFactor
// Maintain the aspect ratio of the original image
var aspectRatio As Double = originalPicture.Width / originalPicture.Height
// Determine the target dimensions based on the lesser of the two constraints
var targetHeight As Integer = maxAllowedHeight
var targetWidth As Integer = targetHeight * aspectRatio
If targetWidth > maxAllowedWidth Then
targetWidth = maxAllowedWidth
targetHeight = targetWidth / aspectRatio
End If
// Create a new Picture object for the resized image
Dim resizedPicture As New Picture(g.Width, g.Height)
// Set high quality anti-aliasing for better scaling quality
resizedPicture.Graphics.AntiAliasMode = Graphics.AntiAliasModes.HighQuality
// Calculate offsets to center the image within the cell
var xOffset As Integer = (g.Width - targetWidth) / 2
var yOffset As Integer = (g.Height - targetHeight) / 2
// Scale and draw the original image into the resized image
resizedPicture.Graphics.DrawPicture(originalPicture, xOffset, yOffset, targetWidth, targetHeight, 0, 0, originalPicture.Width, originalPicture.Height)
g.DrawPicture(resizedPicture, 0, 0)
me.CellTooltipAt(row, column) = me.CellTagAt(row, column).IntegerValue.ToString + "%"
Return True // Indicate that you have handled the drawing
End If
Please pardon my mixed use of Dim and Var, I’m still trying to break old habits for API 2.