Listbox selection color?

Hi all,

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.

Thanks in advance for any tips.

On Windows, your image does have black where the parts are transparent on MacOS ?

Unfortunately, HighlightColor represents the color that should be used when selecting text in a textarea, not listbox rows.

IIRC, on macOS it goes like this: (from memory)

10.14+ should be controlAccentColor
Otherwise selectedControlColor

You can access these colors using code like this (they are case sensitive):

Dim c as color = ColorGroup.NamedColor(" selectedControlColor")

If they’re not right, let me know and I’ll go look on my notes.

@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:

You can see in the “Popularity” column how the color is slightly lighter than the selection color of the rest of the row.

Usually, images without background on Windows appears as black where “transparent” on MacOS.

So make a fast test to validate your test.

Other: it is a good idea to test on other platform during development (vs at later beta stage).

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.

Try controlAccentColor.

Found it, it’s ColorGroup.NamedColor(“selectedContentBackgroundColor”)

Thanks to both @Greg_O and @Emile_Schwarz for your replies, cheers!

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

I’m going to make one more suggestion…

Remember that when the listbox loses focus that the selection color changes. That color is named:

unemphasizedSelectedContentBackgroundColor

1 Like

I case anyone’s wondering how I’m looking these up, I created an app for that:

https://www.dropbox.com/s/2xg43h6n51gaw72/Color%20Swatches.zip?dl=1

2 Likes

:blush:

Edited: A case of brain-fog. If I go to Settings > Privacy & Security > Security Open Anyway, that works.

Thank you Greg!

Can you open it via right-click → Open ??

1 Like

Sam developed an alternative one some time back as well

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!

Thank you Tim, and of course Sam and Greg🤓

Yeah, I didn’t notarize it. Sorry

You may give a try to the Remote Debugger function.

No worries. I knew there was probably a solution, it just took awhile for my brain to find it.

Thanks again.

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

I have not experienced that (the items in the “Popularity” column are all images with transparency):

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. :wink: