1

Using Dyalog APL I'm trying to create a grid with cell tooltips. These tooltips are created with the method AddComment. For some reason the tooltip does not resize itself to fit the content so if the text doesn't fit it will be cut off. Therefor a size calculation is required before the tooltip is created. The method GetTextSize can be used to retrieve the size of a text in pixels for the used font. However, this method seems to report the wrong size despite setting the Coord property to 'Pixel'.

Here is an example which illustrates the problem:

 ∇ ShowGrid;col;comment;height;row;width
   'F'⎕WC'Form'
   'F.G'⎕WC'Grid'(2 2⍴0)(0 0)(100 100)
   comment←↑'line one' 'line two' 'line three'
   row col←1 2
   'F.G' ⎕WS'Coord' 'Pixel'
   height width←4+F.G.GetTextSize comment
   F.G.AddComment row col comment height width
 ∇

I also add four pixels to the reported size of the text since the border and padding of the tooltip seems to be one pixel each. The window created with this function is shown in the image below. Only the text "line one" is visible in the tooltip. I also tried setting Coord to 'RealPixel' and 'ScaledPixel' respectively but it made no difference. My question is basically: What is the proper way to calculate the tooltip size so that any given text will be displayed in its entirety? I'm using Dyalog APL 16.0 Classic.

Grid with cell tooltip

August Karlstrom
  • 10,773
  • 7
  • 38
  • 60
  • 1
    I've forwarded this question to Dyalog support a response may be delayed due to holidays. Please be patient, and we will get back to you. – Adám Dec 22 '22 at 20:41

4 Answers4

2

The comment is drawn with a font that is different to the one used by F.G.GetTextSize. Unfortunately there is currently no simple way to retrieve the size of the font that is actually used.

We will look into ways to fix this.

Adám
  • 6,573
  • 20
  • 37
  • 1
    Note that [John Daintree](https://aplwiki.com/wiki/John_Daintree) is the author of Dyalog APL's `⎕WC` graphics system function. – Adám Dec 23 '22 at 09:30
  • Aha, I didn't notice (or expected) a different font for the comment. – August Karlstrom Dec 23 '22 at 10:52
  • 1
    @AugustKarlstrom Maybe it is possible to determine which font and size is being used, and then compute the size based on that? – Adám Dec 24 '22 at 17:30
1

OK, try this one for 32 bit CLASSIC. The difference is in the SIZE of the structure (504 bytes for a Unicode interpreter, 344 for classic). This is because the font names use 2 byte characters in Unicode and 1 byte characters in classic.

 ⎕IO ⎕ML←1 0
 FNT←' I4 I4 I4 I4 I4 U1 U1 U1 U1 U1 U1 U1 U1 T[32] '                ⍝ A LOGFONT structure
 NCM←'{U4 I4 I4 I4 I4 I4 ',FNT,'I4 I4',FNT,'I4 I4',FNT,FNT,FNT,'I4}' ⍝ A NONCLIENTMETRICSW structure
 SIZE←344                                                            ⍝ The size of the above
 ⎕NA'DYALOG32|MEMCPY >',NCM,' <U1[] U'                               ⍝ Useful copy with format
 ⎕NA'U user32|SystemParametersInfo* U U =U1[',(⍕SIZE),'] U '         ⍝ Get the data as an array of bytes
 r←SystemParametersInfo 41 0(SIZE↑88 1)0
 f←MEMCPY(83⍴0)(2⊃r)SIZE                                             ⍝ And copy to a NCM structure
 tip←f[53 66]                                                        ⍝ And extract the relevant bits
 (2⊃tip)~←⎕UCS 0                                                     ⍝ and remove trailing nulls from name
  • Thanks! This version doesn't crash but it returns a two-element vector where the first element is -12 and the second 'Segoe UI'. What is the interpretation of -12? – August Karlstrom Jan 11 '23 at 08:55
  • I found some information here: https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-logfonta. If the value is negative, the absolute value is the font size (excluding the leading) in logical units. Could it be that the font size is 12 pixels and the leading 3 pixels, which adds up to a line height of 15 pixels as in my example solution with the tooltip font hard coded? – August Karlstrom Jan 11 '23 at 12:53
  • Or is abs(-12) * 96 / 72 = 16 the right calculation given 96 DPI and 72 PPI? – August Karlstrom Jan 11 '23 at 13:08
  • If I use 'Segoe UI' 16 instead of 'Segoe UI' 15 in my solution with a hard coded font I get the same (correct) box size. – August Karlstrom Jan 11 '23 at 13:44
0

A workaround suggested by Adám is to determine and hard code the font used for comments and then use GetTextSize with this font as a parameter. With some guess work and testing I found it to be "Segoe UI" of size 15 pixels. Below is a (rather fragile) solution. It's fragile in the sense that it only works correctly if the user hasn't changed the default font or font size.

∇ ShowGrid;border;col;comment;boxSize;commentSize;padding;row
  'F'⎕WC'Form'
  'F.G'⎕WC'Grid'(2 2⍴0)(0 0)(100 100)
  comment←↑'line one' 'line two' 'line three'
  row col←1 2
  'F.G'⎕WS'Coord' 'Pixel'
  'F.G.FNT'⎕WC'Font' 'Segoe UI' 15
  commentSize←F.G.GetTextSize comment'#.F.G.FNT'
  (border padding)←1
  boxSize←commentSize+2×border+padding
  F.G.AddComment row col comment,boxSize
∇

comment tooltip with all text visible

August Karlstrom
  • 10,773
  • 7
  • 38
  • 60
0

The following is an APL/⎕NA translation of how the interpreter gets thr information about the tip font from the operating system.

∇ tip←tip_font;FNT;NCM;SIZE;⎕IO;⎕ML;SystemParametersInfo;MEMCPY;tip;r;GetLastError;f
 ⎕IO ⎕ML←1 0
 FNT←' I4 I4 I4 I4 I4 U1 U1 U1 U1 U1 U1 U1 U1 T[32] '                ⍝ A LOGFONT structure
 NCM←'{U4 I4 I4 I4 I4 I4 ',FNT,'I4 I4',FNT,'I4 I4',FNT,FNT,FNT,'I4}' ⍝ A NONCLIENTMETRICSW structure
 SIZE←504                                                            ⍝ The size of the above
 ⎕NA'DYALOG64|MEMCPY >',NCM,' <U1[] U'                               ⍝ Useful copy with format
 ⎕NA'U user32|SystemParametersInfo* U U =U1[',(⍕SIZE),'] U '         ⍝ Get the data as an array of bytes
 r←SystemParametersInfo 41 0(SIZE↑248 1)0
 f←MEMCPY(83⍴0)(2⊃r)SIZE                                             ⍝ And copy to a NCM structure
 tip←f[53 66]                                                        ⍝ And extract the relevant bits
 (2⊃tip)~←⎕UCS 0                                                     ⍝ and remove trailing nulls from name
∇