Recent

Author Topic: SOLVED: ChartListBox click area not aligned on icon or checkbox in COCOA  (Read 5529 times)

AL

  • Sr. Member
  • ****
  • Posts: 264
I am reworking a program in MacOS and just found that the ChartListBox is "misaligned"
To make the check appear in the checkbox you have to click on the Icon and to trigger the ChartListBoxIcondblclick, you have to click in the name.  Its like it is shifted some pixels to the right.
This is in MacOS Monterey. Lazarus 2.2.5 / FPC 3.3.1

Attached demo project in MacOS

« Last Edit: November 10, 2022, 03:31:56 pm by AL »
Laz 3.1, fpc 3.2.2, Win10
Laz 3.1  fpc 3.2.2, MacOS Monterey running on VMWare/Win 10
Laz 3.1  fpc 3.2.2 Ubuntu 20.04

wp

  • Hero Member
  • *****
  • Posts: 13264
Re: ChartListBox click area not aligned on icon or checkbox in COCOA
« Reply #1 on: October 30, 2022, 11:37:07 pm »
I cannot reproduce this on macOS Mojave/Laz-main/FPC-3.2.2. I do remember some work with the checkbox and icon rectangles, it was committed in Feb 2020 and should have made it into Laz 2.2.4(5). Please open unit TAChartListbox.pas and check whether it has the following lines at the top:
Code: Pascal  [Select][+][-]
  1. {$IFDEF DARWIN}
  2.   {$DEFINE USE_BITMAPS}
  3. {$ENDIF}
If these lines are missing these old changes are not included in your version. In this case you simply could try to download the current version from https://gitlab.com/freepascal.org/lazarus/lazarus/-/blob/main/components/tachart/tachartlistbox.pas and copy it into your TAChart folder. But make a backup copy first since I am not sure whether this file will compile in your system.

AL

  • Sr. Member
  • ****
  • Posts: 264
Re: ChartListBox click area not aligned on icon or checkbox in COCOA
« Reply #2 on: October 31, 2022, 03:25:20 pm »
The Define is there. 
I made that some years ago with Laz 2.1 and it was working fine in Mojave.
I have updated to Monterey and now I have this behavior.  I am not sure why.  Does MacOs 12 have a different pixel resolution ?
There is a const Margin = 4 in procedure CalcRecs.  Is it enough to shift the click zone?
If I remove this margin do i have to recompile the package and rebuild the IDE also?
« Last Edit: October 31, 2022, 03:27:33 pm by AL »
Laz 3.1, fpc 3.2.2, Win10
Laz 3.1  fpc 3.2.2, MacOS Monterey running on VMWare/Win 10
Laz 3.1  fpc 3.2.2 Ubuntu 20.04

wp

  • Hero Member
  • *****
  • Posts: 13264
Re: ChartListBox click area not aligned on icon or checkbox in COCOA
« Reply #3 on: October 31, 2022, 05:15:25 pm »
Reading your initial description again, I understand that checkbox and series icon are shown, but it looks as if the checkbox is not considered when the mouse click is evaluated. Right?

The Define is there. 
I made that some years ago with Laz 2.1 and it was working fine in Mojave.
I have updated to Monterey and now I have this behavior. 
I see. But I refrain from setting up another virtual machine with macOS...

There is a const Margin = 4 in procedure CalcRecs. 
I think this is just a "beautifying" margin and is harmless

Probably the issue is in the determination of FCheckBoxSize which depends on the ThemeServices, and I remember that there were issues with it on mac. What happens when you add a line "FCheckBoxSize.CX := 24" at the end of the "if cloShowCheckboxes in Options" block, immediately before the "end;", in TChartListbox.DrawItem, so that the following CalcRects definitely gets a non-zero, somehow reasonable, FCheckboxSize value?

If I remove this margin do i have to recompile the package and rebuild the IDE also?
After every change in package code you must recompile the package (open tachartlazaruspackage.lpk and click the "Compile" button in the package editor), but often the IDE does this automatically. Rebuilding the IDE normally is not required, only when the change affects the designtime behaviour of the package.

AL

  • Sr. Member
  • ****
  • Posts: 264
Re: ChartListBox click area not aligned on icon or checkbox in COCOA
« Reply #4 on: October 31, 2022, 10:30:15 pm »
Reading your initial description again, I understand that checkbox and series icon are shown, but it looks as if the checkbox is not considered when the mouse click is evaluated. Right?

Yes both are shown, but to check or uncheck the checkbox I have to click just beside it ( in the icon). 
And to doublelick the icon I have to click beside it ( to the right) in the name.  It is like in both cases, the click area is defined some pixels to the right of where it should be.  Both work and the procedures are called (once you find where to click).
Laz 3.1, fpc 3.2.2, Win10
Laz 3.1  fpc 3.2.2, MacOS Monterey running on VMWare/Win 10
Laz 3.1  fpc 3.2.2 Ubuntu 20.04

wp

  • Hero Member
  • *****
  • Posts: 13264
Re: ChartListBox click area not aligned on icon or checkbox in COCOA
« Reply #5 on: November 01, 2022, 12:43:17 am »
What about FCheckboxSize?

AL

  • Sr. Member
  • ****
  • Posts: 264
Re: ChartListBox click area not aligned on icon or checkbox in COCOA
« Reply #6 on: November 01, 2022, 03:22:55 am »
I will try that a bit later
Laz 3.1, fpc 3.2.2, Win10
Laz 3.1  fpc 3.2.2, MacOS Monterey running on VMWare/Win 10
Laz 3.1  fpc 3.2.2 Ubuntu 20.04

AL

  • Sr. Member
  • ****
  • Posts: 264
Re: ChartListBox click area not aligned on icon or checkbox in COCOA
« Reply #7 on: November 01, 2022, 02:43:00 pm »
The CheckBoxSize has no effect, removing the margin has also no effect.

The more I look at it, it seems to me that the click area is a flipped (on the vertical axis) mirror image of the shown checkbox or of the icon.  Are the Mac screen coordinate not reversed compared to windows?
Laz 3.1, fpc 3.2.2, Win10
Laz 3.1  fpc 3.2.2, MacOS Monterey running on VMWare/Win 10
Laz 3.1  fpc 3.2.2 Ubuntu 20.04

wp

  • Hero Member
  • *****
  • Posts: 13264
Re: ChartListBox click area not aligned on icon or checkbox in COCOA
« Reply #8 on: November 01, 2022, 03:23:06 pm »
it seems to me that the click area is a flipped (on the vertical axis) mirror image of the shown checkbox or of the icon.
You mean that the positions of the checkbox and the series icon are exchanged? Normally the checkbox is at the very left, and the series icon is between the checkbox and the text. While the checkbox is (well: should be...) always the same size, the size of the series icons can be changed by modifying the value of the SymbolWidth property of the chart's Legend (this value is reused by the chartlistbox). So, when you increase this to, say, 100, the series icon should be very wide compared to the checkbox. When you now click there should also be a much wider range of click positions which hit the icon than the checkbox. Is this correct?

BTW: What is the BiDiMode setting of the ChartListbox? It would exchange left and right, i.e. move the checkbox to the very right of the listbox, and the text to the very left. It should have a visual effect, but who knows what bugs are in the weakly-tested mac code of the chartlistbox?

Are the Mac screen coordinate not reversed compared to windows?
I have no idea, I am no mac specialist. But wouldn't this affect all gui controls?
« Last Edit: November 01, 2022, 03:26:17 pm by wp »

AL

  • Sr. Member
  • ****
  • Posts: 264
Re: ChartListBox click area not aligned on icon or checkbox in COCOA
« Reply #9 on: November 01, 2022, 06:55:03 pm »
You mean that the positions of the checkbox and the series icon are exchanged? Normally the checkbox is at the very left, and the series icon is between the checkbox and the text.
BTW: What is the BiDiMode setting of the ChartListbox?
No, everything is placed as it should.  It is only the area which detect the MouseDown Event that seems to be shifted from the display. I cannot explain it properly as I am not familiar with how this is done. 
Are the Mac screen coordinate not reversed compared to windows?
I have no idea, I am no mac specialist. But wouldn't this affect all gui controls?
[/quote]
I guess it should

If I modify this line of the  CalcRects procedure
 
 OffsetRect(ACheckboxRect, X , (AItemRect.Top + AItemRect.Bottom - FCheckboxSize.CY) div 2);
(replacing x with XFCheckBoxSize.CX )
OffsetRect(ACheckboxRect,(XFCheckBoxSize.CX ), (AItemRect.Top + AItemRect.Bottom - FCheckboxSize.CY) div 2);

then the checkbox and the click area are aligned .  I can check and uncheck the checkBox by clicking in the CheckBox.  However there is a wide margin at the left.  Possibly this is not the correct place to modify.  But there is certainly a miscalculation of these Rectangles.
Laz 3.1, fpc 3.2.2, Win10
Laz 3.1  fpc 3.2.2, MacOS Monterey running on VMWare/Win 10
Laz 3.1  fpc 3.2.2 Ubuntu 20.04

wp

  • Hero Member
  • *****
  • Posts: 13264
Re: ChartListBox click area not aligned on icon or checkbox in COCOA
« Reply #10 on: November 01, 2022, 07:52:55 pm »
I think you must help me and use the debugger: In your test project, go to "Project Options" > "Additions and Overrides", click "Add" > "Custom option", then click into the line "Custom" (below "Targets") and type "-gw3" (without quotes). Close with "OK". When you now compile your project, all required packages will be build with debug information so that you can step into their code with the debugger.

Set the following breakpoints in procedure TChartListbox.CalcRects by clicking in the gutter at the left of the following lines:
/1/ "if cloShowcheckboxes in Options..."
/2/ "OffsetRect(ACheckBoxRect..."
/3/ "if cloShowIcons in Options..."
/4/ "end";" of the procedure.
A set breakpoint is indicated by a red bullet in the gutter line.

Now run the test program. It should contain only single series. It will stop at the first breakpoint. Move the mouse over the variables "isRTL", "x", "AItemRect", "FCheckBoxSize", read their values from the popup windows and write them down (you have to post them here to the forum).

Now select "Run" > "Run" to stop at the next breakpoint (or press F9 - I think it requires classic keyboard layout, though). Record the values of "x" and "ACheckboxRect"

Press "Run" > "Run" again, record "x" and "ACheckboxRect".

Another "Run" > "Run", and record "ASeriesIconRect".

A final "Run" > "Run" continues the program without further interruption (unless your chart contains more than a single series). You can also press "Run" > "Stop" to terminate the program

Post the recorded values.

These are the results that I see in my Mojave:
/1/ Breakpoint at "if (cloShowCheckboxes": isRTL = false, x = 4, AItemRect = (Left:0, Top:0, Right:98, Bottom:18), FCheckboxSize = (cx:22, cy:18)
/2/ Breakpoint at "OffsetRect": x = 4, ACheckboxRect = (Left:0, Top:0, Right:22, Bottom:18)
/3/ Breakpoint at "if cloShowIcons": x=30, ACheckboxRect = (Left:4, Top:0, Right:26: Bottom:18)
/4/ Breakpoint at "end": SeriesIconRect = (Left:30, Top:1; Right:50; Bottom:16)

Depending on the result we'll probably have to repeat this several times.

« Last Edit: November 02, 2022, 12:34:02 am by wp »

AL

  • Sr. Member
  • ****
  • Posts: 264
Re: ChartListBox click area not aligned on icon or checkbox in COCOA
« Reply #11 on: November 01, 2022, 11:18:47 pm »
Debugger is lldb with FPdebug

These are the results that I see in Monterey:

/1/ Breakpoint at "if (cloShowCheckboxes":
     isRTL = I do not have a isRTL !!
     x = 4, AItemRect = (Left:0, Top:10, Right:206, Bottom:258), FCheckboxSize =   (cx:18, cy:18)
/2/ Breakpoint at "OffsetRect": x = 4, ACheckboxRect = (Left:0, Top:0, Right:18, Bottom:18)
/3/ Breakpoint at "if cloShowIcons": x=30, ACheckboxRect = (Left:4, Top:8, Right:22: Bottom:26)
/4/ Breakpoint at "end": SeriesIconRect = (Left:26, Top:12; Right:46; Bottom:23)

I do not have a isRtl variable. May be my TaChart is not the last one.
This is my procedure CalcRects:

Code: Pascal  [Select][+][-]
  1. procedure TChartListbox.CalcRects(
  2.   const AItemRect: TRect; out ACheckboxRect, ASeriesIconRect: TRect);
  3. { based on the rect of a listbox item, calculates the locations of the
  4.   checkbox and of the series icon }
  5. const
  6.   MARGIN = 4;
  7. var
  8.   x: Integer;
  9. begin
  10.   ACheckBoxRect := ZeroRect;
  11.   ASeriesIconRect := ZeroRect;
  12.  
  13.   x := AItemRect.Left + MARGIN;
  14.   if cloShowCheckboxes in Options then begin
  15.     ACheckBoxRect := Rect(0, 0, FCheckboxSize.CX, FCheckboxSize.CY);
  16.    OffsetRect(ACheckboxRect,X, (AItemRect.Top + AItemRect.Bottom - FCheckboxSize.CY) div 2);
  17.    if cloShowIcons in Options then
  18.       x += ACheckboxRect.Right;
  19.   end
  20.   else begin
  21.     if cloShowIcons in Options then
  22.       x += AItemRect.Left;
  23.   end;
  24.   if cloShowIcons in Options then
  25.     ASeriesIconRect := Rect(
  26.       x, AItemRect.Top + 2, x + FChart.Legend.SymbolWidth, AItemRect.Bottom - 2);
  27. end;
  28.  
Laz 3.1, fpc 3.2.2, Win10
Laz 3.1  fpc 3.2.2, MacOS Monterey running on VMWare/Win 10
Laz 3.1  fpc 3.2.2 Ubuntu 20.04

wp

  • Hero Member
  • *****
  • Posts: 13264
Re: ChartListBox click area not aligned on icon or checkbox in COCOA
« Reply #12 on: November 02, 2022, 01:03:42 am »
Hmmm...

These numbers look correct: The checkbox rectangle extends between Left=4 and Right=22, and the series icon rectangle between Left=26 and Right=46 -- the series icon is at the right of the checkbox, like it should be.

But in your code there are three locations with "if cloShowIcons". You hopefully have set the break point on the third one.

The "if cloShowIcons in Options then  x += ACheckboxRect.Right;" looks incorrect: Because the checkbox rect already has been moved the icon will be too far at the right. But I think this does not cause not your issue.

The missing isRTL variable indicates that you do not have the same version as I. Maybe it's worth a try to copy the trunk version over your version. I just checked that this should compile with Laz-fixes -- you said that you have Laz 2.2.5, didn't you? I am attaching a zipped copy of the chartlistbox unit. Save the unzipped file it in the TAChart folder of your Laz 2.2.5 installation (but make a backup copy of TAChartListbox.pas first!). Recompile the tachartlazaruspkg again although I don't think that it's necessary.

Maybe this fixes the issue (but I don't believe so...)

If it does not, we should try another debugging round, now in the MouseDown procedure of the TChartListbox.
- Set breakpoints on "ClickedCheckbox", "FSeriesIconClicked := .." and "ClickedItem"
- Run and click on the checkbox. The program should stop on one of the breakpoints after the click. Which one is it? Report the values of the variables "p", "rcb", "ricon" and "index".
- Then continue the program and click on the series icon now. Repeat the checks.
« Last Edit: November 02, 2022, 01:42:58 am by wp »

AL

  • Sr. Member
  • ****
  • Posts: 264
Re: ChartListBox click area not aligned on icon or checkbox in COCOA
« Reply #13 on: November 02, 2022, 02:12:37 am »
The updated code did not solved the problem.
This is becomming interesting!

If I click IN the checkbox then the breakpoint goes to
" else
      ClickedItem(index);  "

This mean the IsPointInRect was false

If I click between the CheckBox and the Icon then it stop at "ClickedCheckbox(index)"

Same for the Icon.
If I click on the Icon it goes to "ClickedCheckbox(index)" most of the time
If I click beside the Icon (Almost on the 'C') then it stop at "FSeriesIconClicked := index" 

Here are the numbers:
Click    In checkBox  Between CheckBox and Icon  On Icon     On the 'C'
p x          17                       27                                 50                62
p y          17                       16                                 18                 17

RCB Top   8                          8                                   8                  8
        Bot  26                       26                                 26                26
        Left  20                       20                                 20                20
      Right  38                       38                                 38                 38

Ricon Top   10                      10                                  10               10
          Bot  25                      25                                  25               25
         Left   42                     42                                  42                42
         Right 62                      62                                  62                62
Index           0                         0                                   0                  0

It seems that P is not right.

Thank you for your help
Laz 3.1, fpc 3.2.2, Win10
Laz 3.1  fpc 3.2.2, MacOS Monterey running on VMWare/Win 10
Laz 3.1  fpc 3.2.2 Ubuntu 20.04

wp

  • Hero Member
  • *****
  • Posts: 13264
Re: ChartListBox click area not aligned on icon or checkbox in COCOA
« Reply #14 on: November 02, 2022, 11:27:34 am »
Why did the checkbox rect (rcb) move to the right now? It now extends between Left=20 and Right=38. But in the previous test, it was between Left=4 and Right=22.

Code: Pascal  [Select][+][-]
  1. procedure TChartListbox.CalcRects(
  2.   const AItemRect: TRect; out ACheckboxRect, ASeriesIconRect: TRect);
  3. const
  4.   MARGIN = 4;
  5. var
  6.   x, y, h: Integer;
  7.   isRTL: Boolean;
  8. begin
  9.   ACheckBoxRect := ZeroRect;
  10.   ASeriesIconRect := ZeroRect;
  11.   isRTL := IsRightToLeft;
  12.  
  13.   x := IfThen(isRTL, AItemRect.Right - MARGIN, AItemRect.Left + MARGIN);
  14.  
  15.   if cloShowCheckboxes in Options then begin
  16.     ACheckBoxRect := Rect(0, 0, FCheckboxSize.CX, FCheckboxSize.CY);
  17.     if isRTL then dec(x, FCheckboxSize.CX);
  18.     OffsetRect(ACheckboxRect, x, (AItemRect.Top + AItemRect.Bottom - FCheckboxSize.CY) div 2);
  19.     if cloShowIcons in Options then
  20.       x := IfThen(isRTL, ACheckboxRect.Left - MARGIN, ACheckboxRect.Right + MARGIN);
  21.   end;
  22.  
  23.   if cloShowIcons in Options then
  24.   begin
  25.     h := CalculateStandardItemHeight;
  26.     y := (AItemRect.Top + AItemRect.Bottom - h) div 2;
  27.     if isRTL then
  28.       ASeriesIconRect := Rect(x - FChart.Legend.SymbolWidth, y, x, y + h)
  29.     else
  30.       ASeriesIconRect := Rect(x, y, x + FChart.Legend.SymbolWidth, y + h);
  31.   end;
  32. end;              

ACheckboxRect (which becomes rcb in MouseDown) starts here with Left=0, Right=FCheckboxSize.CX=18 in the "if cloShowCheckboxes in Options" condition (line 16). Then, in the OffsetRect line 18, it is shifted to the right by x, and x had been determined in line 13 to be 4 (AItemRect.Left = 0, Margin = 4). So, ACheckboxRect should begin at Left=4, but not at 20. And since FCheckBoxSize.CX is 18 the right edge should be 22, but not 38. What's going on here?

Please repeat the previous test with breakpoints in CalcRects. But this time set an additional breakpoint on the CalcRects line in MouseDown. This is because it seems that CalcRects is called several times (for painting). So, when you run the program it will stop in the first CalcRects breakpoint, but this is not what I want since CalcRects is called from the painting routine here. Press "Run" > "Run" as often as needed until the program stops at the breakpoint in the MouseDown procedure. With the next "Run" > "Run" the program will be in CalcRects again, but now in the state which I am interested in. Now record and report the variable values as described above.

 

TinyPortal © 2005-2018