This works, but doesn’t really work:
Var Group As New ColorGroup("alternatingContentBackgroundColors")
When you use the color, you’ll get the first color in the array. There doesn’t appear to be a way to get the second color. So it doesn’t really work.
So I have this semi-functional alternative
Var Colors(1) As Color
#if TargetMacOS
Declare Function objc_getClass Lib "Cocoa" (ClassName As CString) As Ptr
Declare Function NSSelectorFromString Lib "Cocoa" (SelectorName As CFStringRef) As Ptr
Declare Function RespondsToSelector Lib "Cocoa" Selector "respondsToSelector:" (Target As Ptr, Sel As Ptr) As Boolean
Var NSColor As Ptr = objc_getClass("NSColor")
Var ArrayRef As Ptr
If RespondsToSelector(NSColor, NSSelectorFromString("alternatingContentBackgroundColors")) Then
Declare Function RowColors Lib "Cocoa" Selector "alternatingContentBackgroundColors" (Target As Ptr) As Ptr
ArrayRef = RowColors(NSColor)
Else
Declare Function RowColors Lib "Cocoa" Selector "controlAlternatingRowBackgroundColors" (Target As Ptr) As Ptr
ArrayRef = RowColors(NSColor)
End If
Declare Function ArrayCount Lib "Cocoa" Selector "count" (Target As Ptr) As UInteger
Declare Function ArrayObjectAtIndex Lib "Cocoa" Selector "objectAtIndex:" (Target As Ptr, Index As UInteger) As Ptr
Declare Function GetGenericRGBColorSpace Lib "Cocoa" Selector "deviceRGBColorSpace" (Target As Ptr) As Ptr
Declare Function ColorUsingColorSpace Lib "Cocoa" Selector "colorUsingColorSpace:" (Target As Ptr, ColorSpace As Ptr) As Ptr
Declare Sub GetRGBValues Lib "Cocoa" Selector "getRed:green:blue:alpha:" (Target As Ptr, ByRef Red As CGFloat, ByRef Green As CGFloat, ByRef Blue As CGFloat, ByRef Alpha As CGFloat)
Var ObjectCount As UInteger = ArrayCount(ArrayRef)
Var Bound As Integer = CType(ObjectCount, Integer) - 1
Var NSColorSpace As Ptr = objc_getClass("NSColorSpace")
Var ColorSpace As Ptr = GetGenericRGBColorSpace(NSColorSpace)
Colors.ResizeTo(Bound)
For I As Integer = 0 To Bound
Var Handle As Ptr = ColorUsingColorSpace(ArrayObjectAtIndex(ArrayRef, CType(I, UInteger)), ColorSpace)
If Handle = Nil Then
Colors(I) = &cFB02FE00
Continue
End If
Var RedValue, GreenValue, BlueValue, AlphaValue As CGFloat
GetRGBValues(Handle, RedValue, GreenValue, BlueValue, AlphaValue)
Colors(I) = Color.RGB(255 * RedValue, 255 * GreenValue, 255 * BlueValue, 255 - (AlphaValue * 255))
Next
// This is to work around an issue where the even dark color isn't getting the proper alpha channel
// https://forum.xojo.com/50440-dark-mode-alternatingcontentbackgroundcolors-doesn-t-seem-corre
If SystemColors.IsDarkMode Then
Colors(0) = Color.RGB(Colors(0).Red, Colors(0).Green, Colors(0).Blue, 153)
End If
Return Colors
#endif
The trouble is it doesn’t really match with the design of ColorGroup. There’s no way for me to pass the handle of the NSColor to ColorGroup so it can render the final color when needed. I need to pre-render the colors and pack them into a static ColorGroup. It “works” but also defeats the purpose of using ColorGroup.
I don’t think I’ve missed anything, so really I’m just looking for confirmation that there isn’t a way to get this right.