CueText Color frustrations in Dark Mode

  1. 3 months ago

    Tim J

    Apr 14 Pre-Release Testers, Xojo Pro Dehydrating in AZ

    Others have mentioned it and I'm witnessing the same situation in my app - the macOS CueText color doesn't work well with dark backgrounds in TextField or TextArea controls. It appears that the CueText color is relative to the control's back color. This means that manually adjusting the control's back color manually still doesn't help since the CueText color changes to match the new back color.

    It appears that showing or hiding a label based on the "GotFocus/LostFocus" events of the TextField/TextArea is the only way to accomplish a consistent CueText. This works on all three platforms. For example:

    Sub GotFocus()
      tfSetNameCueText.Visible = False
    End Sub
    Sub LostFocus()
      If Me.Text = "" Then
        tfSetNameCueText.Visible = True
      End If
    End Sub

    We're back to REALbasic 5 ... Kind of makes the CueText property useless in non-default color themes.

  2. Markus W

    Apr 14 Pre-Release Testers #JeSuisHuman New Zealand, Auc...

    Personally I prefer a separate label at the bottom of the Window anyway. Using MouseEnter and MouseExit the help text is shown instantly, does not obstruct anything, and doesn’t vanish before I read it.

  3. Sam R

    Apr 14 Pre-Release Testers, Xojo Pro Hengchun, Pingtung, Taiwan

    Xojo's not entirely to blame here, the CueText property or "placeHolder" uses an NSAttributedString. There is no actual property for setting the CueText color (that I'm aware of).

    The following code uses ma huge azz library (which I can't share right at this moment), but the code it'self should give you an idea of what's needed to change the color of the CueText. Oh and the application will crash if you use this when there isn't a CueText already set.

    How to get the CueText color.

    declare function getValue lib AppKit selector "placeholderTextColor" ( NSColorClass as integer ) as integer

    How to set it on a TextField.

    Public Sub placeholderTextColor(extends inField as TextField, assigns inColor as color)
      #if targetMacOS then
        // --- First we grab some settings from the TextField.
        //     We need to create a NSFont, so we'll need the font name and font size.
        //     Sam Rowlands, Nov 2018
        
        Dim fontName as string = inField.textFont
        Dim fontSize as single = inField.textSize
        
        if fontName = "SmallSystem" then // --- We want the smallSystem font.
          if fontSize = 0 then fontSize = NSFontSmallSystemFontSize( NSFontClass )
          fontName = "System"
          
        elseif fontSize = 0 then
          fontSize = NSFontSystemFontSize( NSFontClass )
          
        end if
        
        // --- Now we can create a NSFont
        Dim theFont as integer
        if fontName = "System" or fontName = "" then
          theFont = NSFontSystemFontOfSize( NSFontClass, fontSize, NSFontWeight( NSFontWeightRegular ) )
          
        else
          theFont = NSFontWithName( NSFontClass, fontName, fontSize )
          
        end if
        
        // --- Now we can create a NSColor
        Dim theColor as integer = NSColor( inColor )
        
        // --- We create an "string attributes" dictionary.
        Dim attribs as integer = NSDictionaryWithObjectsForKeys( theFont : "NSFont", theColor : "NSColor" )
        
        // --- We create an attributed string.
        Dim attribString as integer = NSAttributedStringWithAttributes( inField.cueText, attribs )
        
        // --- FInally we set that onto the text field.
        declare sub setValue lib "AppKit" selector "setPlaceholderAttributedString:" ( NSTextFieldCellInstance as integer, NSAttributedStringInstance as integer )
        setValue( NSCellFromNSControl( inField.handle ), attribString )
        
        NSObjectRelease attribString
      #endif
    End Sub

    Hope that this helps.

  4. Tim J

    Apr 15 Pre-Release Testers, Xojo Pro Dehydrating in AZ

    I popped that in, Sam, but my label method is actually more successful and works on all three platforms.

    I understand your point, Markus. But the wizard that I'm working with doesn't have a design permitting a "status bar" area. And, my mechanism works just like the CueText mechanism with next to no overhead.

or Sign Up to reply!