Dynamically aligning SF Symbols and labels to make a list

I’ve spent several days, first attempting to do the alignment with native Xojo (and a picture/graphics) and still couldn’t get it right.

Yesterday after spelunking, I found the macOS API that I needed (which of course isn’t exposed by Xojo). So I present to you the code I’ve created to be able to align an imagewell control array and a label control array.

// --- Now align the label control array and the imagewell control array.
const maxIconWidth as integer    =  16
const iconPlusPadding as integer =  20
Dim rowTop as double             = 100
Dim rowMinHeight as double       =  24
Dim textTopOffset, textHeight, labelVPadding as double
Dim textFont as integer
Dim contentSize as NSSize

For l as integer = 0 to lastAddedRowIndex
  // --- Vertically center a Xojo Label or NSTextField.
  //     1. This works by obtaining the "baseline", then calulating the textTopOffset and the textHeight
  //        from the label's typeface. We then center on the text height, and use the offset to shift 
  //        the label/field up.
  //     2. Xojo doesn't support floats for control placement, so we MUST round the font attribue values.
  
  textFont            = NSTextField_font( stLabel( l ).handle )
  textTopOffset       = NSView_firstBaselineOffsetFromTop( stLabel( l ).handle )   - round(  NSFont_ascender( textFont ) )
  textHeight          = ( NSView_firstBaselineOffsetFromTop( stLabel( l ).handle ) - round( NSFont_descender( textFont ) ) ) - textTopOffset
  labelVPadding       = ( ( rowMinHeight - textHeight ) / 2.0 ) - textTopOffset
  stLabel( l ).top    = labelVPadding + rowTop
  
  // --- Now we can set the height of the field, we'll just ask the macOS for that.
  contentSize.width   = stLabel( l ).width                                         // --- Must be reset each time we use it.
  contentSize.height  = 3000                                                       // --- we set this to the max value we can think of.
  contentSize         = NSControl_sizeThatFits( stLabel( l ).handle, contentSize ) // --- This little gem, gives us the text size!
  stLabel( l ).height = contentSize.height
  
  
  // --- Now align the SF Symbols.
  //     1. SF Symbols can be really weird sizes, not just odd numbers, but even half numbers. Xojo uses
  //        integers only, so we have to size the imagewell to a multiple of 2.
  //     2. Once we have the height of the imagewell, we can then center that based upon the matching
  //        text rendering measurements we got while centering the label/field.
  
  icon               = NSImageView_image( stIcon( l ).handle )
  stIcon( l ).width  = ceil( ceil( NSImage_size( icon ).width )  / 2.0 ) * 2.0
  stIcon( l ).height = ceil( ceil( NSImage_size( icon ).height ) / 2.0 ) * 2.0
  stIcon( l ).left   = ( ( maxIconWidth - stIcon( l ).width )  / 2.0 ) + ( stLabel( l ).left - iconPlusPadding )
  sticon( l ).top    = ( ( textHeight   - stIcon( l ).height ) / 2.0 ) + ( stLabel( l ).top  + textTopOffset )
  
  // --- incredment the row height, by either the miniumRowHeight or if the text is too great, but that and the padding.
  rowTop              = rowTop + max( rowMinHeight, stLabel( l ).height + ( labelVPadding * 2.0 ) )
next

yeah baselines should be exposed

but arent :frowning:

content rect and a few others well … are “platform specific” so not surprised they aren’t but man it’d be useful

1 Like

Looks like Xojo has very poor undertanding of what a FRAMEWORK is. Even B4X has a CONSISTENT graphics framework to create consistent pictures on every target.

They expose the common framework to the user and solve the “platform specific” UNDER the hood instead of the xojo way of, sorry is different on each platform and they are lazy or incompetent to solve the differences.

2 Likes

Indeed
If it were JUST between GUI apps on macOS Linux & Windows that can be solved. Each underlying OS has functions to do baseline alignments and several others
But take code from a GUI app and use it in a console app and you’ll very different results between the same code in a GUI app and a console app

These are the sort of discrepancies that should be solved so the code written produces the same output regardless
It would certainly make these two claims ring true

Screen Shot 2023-06-11 at 10.00.08 AM

1 Like