Recent

Author Topic: TGroupBox.AutoSize is broken?  (Read 1182 times)

LemonParty

  • Sr. Member
  • ****
  • Posts: 415
TGroupBox.AutoSize is broken?
« on: August 10, 2025, 01:09:47 pm »
Hello.
I have a TGroupBox and I create few checkboxes in runtime inside this groupbox. The problem is that groupbox not expanding so only few first checkboxes are visible. Is this some kind of bug or it should be like this?
Lazarus v. 4.99. FPC v. 3.3.1. Windows 11

wp

  • Hero Member
  • *****
  • Posts: 13412
Re: TGroupBox.AutoSize is broken?
« Reply #1 on: August 10, 2025, 02:20:39 pm »
Cannot confirm. The attached demo works correctly (Laz/main + fpc 3.2.2, Windows 11). Please post a similar demo to show the issue.

jamie

  • Hero Member
  • *****
  • Posts: 7599
Re: TGroupBox.AutoSize is broken?
« Reply #2 on: August 10, 2025, 02:54:30 pm »
This works for me on my Windows 11 flapTop.

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.   CheckGroup1.Items.Add(DateTimeToStr(Now));
  4. end;
  5.                        
  6.  

Did you set a constraint?

jamie
The only true wisdom is knowing you know nothing

LemonParty

  • Sr. Member
  • ****
  • Posts: 415
Re: TGroupBox.AutoSize is broken?
« Reply #3 on: August 10, 2025, 03:06:09 pm »
wp, I added a scrollbox to your example and behavior of groupbox changed.

jamie, no I didn't.
Lazarus v. 4.99. FPC v. 3.3.1. Windows 11

wp

  • Hero Member
  • *****
  • Posts: 13412
Re: TGroupBox.AutoSize is broken?
« Reply #4 on: August 10, 2025, 04:58:37 pm »
I see. But when I set Groupbox.AutoSize=true in code (activated the commented-out line at the end) the behaviour is correct again.

It was strange, though, that I could not restore the erroneous behaviour any more, i.e. even when I commented out the AutoSize line again I still got the correct behaviour. Only after reloading your original files the error was back.

Looking at the lfm file I saw that you are working at a monitor resolution of 192 ppi, my system is at 96 ppi. So, this issue is related to LCL scaling. And indeed, LCL scaling requires special attention when controls are created at runtime.

In your system at 192 ppi all dimensions are thought to be valid for this specific resolution. In my code I placed the checkboxes at y positions of 0, 20, 40, 60 and 80 pixels, thinking that this is perfect for my screen at 96ppi where the height of a checkbox is 19 pixels (on Windows). But for 192 ppi, this is way too narrow because the height of a TCheckbox at this resolution should by 2*19 = 38 pixels (+/-). But when the Top positions are scaled manually everything should be fine:
Code: Pascal  [Select][+][-]
  1. [...]
  2.   with TCheckbox.Create(self) do
  3.   begin
  4.     Caption := 'This is checkbox 2';
  5.     Parent := Groupbox1;
  6.     Borderspacing.Left := 12;
  7.     BorderSpacing.Right := 12;
  8.     Top := Scale96ToForm(20);
  9.   end;
  10. [...]

Scale96ToForm assumes that the provided length argument is valid for 96 ppi and multiplies it by the ratio of the PixelsPerInch of the form to 96.

On my system running at 96 ppi, the situation is a bit more complex because during reading of the lfm file the different resolution is detected, and the central scaling procedure AutoAdjustLayout is executed at the end of the of construction process, and in particular after the OnCreate handler where the checkboxes are created. AutoAdjustLayout corrects all dimensions in the ratio of the current resolution to the designtime resolution. While the vertical checkbox positions were correct in the OnCreate handler the following AutoAdjustLayout moved them up by 50% (=96/192) - same result as in your case: overlapping checkboxes... But the solution is the same: When I manually scale the Top positions as shown above, everything is fine (BTW, the Borderspacings should be scaled, too).

And why couldn't I restore the error behaviour after uncommenting the "Autoscale" line and then commenting it again? Because the project is saved before running, and and this step the lfm is rewritten with my current screen resolution. Afterwards the dimensions in the file are for 96ppi and the dimensions of the checkboxes are for 96 ppi, too - perfect match. And Scale96ToForm is not harmful either, because it just multiplies dimensions here by 1.

jamie

  • Hero Member
  • *****
  • Posts: 7599
Re: TGroupBox.AutoSize is broken?
« Reply #5 on: August 10, 2025, 05:12:05 pm »
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. Var
  3.   H:Integer;
  4. begin
  5.   H := Trunc(Canvas.TextHeight('H')*1.25);
  6.   with TCheckbox.Create(self) do
  7.   begin
  8.     Caption := 'Checkbox 1';
  9.     Parent := Groupbox1;
  10.     Borderspacing.Left := 12;
  11.     BorderSpacing.Right := 12;
  12.     Top := 0*H;
  13.   end;
  14.  
  15.   with TCheckbox.Create(self) do
  16.   begin
  17.     Caption := 'This is checkbox 2';
  18.     Parent := Groupbox1;
  19.     Borderspacing.Left := 12;
  20.     BorderSpacing.Right := 12;
  21.     Top := 1*H;
  22.   end;
  23.  
  24.   with TCheckbox.Create(self) do
  25.   begin
  26.     Caption := 'cb3';
  27.     Parent := Groupbox1;
  28.     Borderspacing.Left := 12;
  29.     BorderSpacing.Right := 12;
  30.     BorderSpacing.Bottom := 6;
  31.     Top := 2*H;
  32.   end;
  33.  
  34.   with TCheckbox.Create(self) do
  35.   begin
  36.     Caption := 'The checkbox #4';
  37.     Parent := Groupbox1;
  38.     Borderspacing.Left := 12;
  39.     BorderSpacing.Right := 12;
  40.     BorderSpacing.Bottom := 6;
  41.     Top := 3*H;
  42.   end;
  43.  
  44.   with TCheckbox.Create(self) do
  45.   begin
  46.     Caption := 'and #5';
  47.     Parent := Groupbox1;
  48.     Borderspacing.Left := 12;
  49.     BorderSpacing.Right := 12;
  50.     BorderSpacing.Bottom := 6;
  51.     Top := 4*H;
  52.   end;
  53.  
  54. //  Groupbox1.AutoSize := true;
  55. end;                                                    
  56.  
  57.  

 I use the font height because it changes with scaling.
The only true wisdom is knowing you know nothing

jamie

  • Hero Member
  • *****
  • Posts: 7599
Re: TGroupBox.AutoSize is broken?
« Reply #6 on: August 10, 2025, 05:40:42 pm »
a TFlowPanel works well for this. You can adjust it to your choice and easy to add check boxes

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.   With TCheckBox.Create(FlowPanel1) do
  4.     Begin
  5.       Caption := DateTimeTostr(Now);
  6.       Parent := FlowPanel1;
  7.     end;
  8. end;                                        
  9.  
  10.  

Set the AutoSize to true.

jamie
The only true wisdom is knowing you know nothing

LemonParty

  • Sr. Member
  • ****
  • Posts: 415
Re: TGroupBox.AutoSize is broken?
« Reply #7 on: August 10, 2025, 08:27:37 pm »
I have 1 more problem. This is 2 groupboxes that should be rendered 1 below other.
Code that creates them is follow:
Code: Pascal  [Select][+][-]
  1.   gbFilePropertiesToCopy.Left:= 16;
  2.   gbFilePropertiesToCopy.Top:= y;
  3.   z:= 16;
  4.   for o in [wmdofpData..wmdofpAuditingInformation] do begin
  5.     CreateCheckBox(o, gbFilePropertiesToCopy, 16, z);
  6.     inc(z, TCheckBox(FWOArray[o]).Height + CGap);
  7.   end;
  8.   inc(y, gbFilePropertiesToCopy.Height + CGap);
  9.  
  10.   gbDirectoryPropertiesToCopy.Left:= 16;
  11.   gbDirectoryPropertiesToCopy.Top:= y;
  12.   z:= 16;
  13.   for o in [wmdodpData..wmdodpSkipAltDataStreams] do begin
  14.     CreateCheckBox(o, gbDirectoryPropertiesToCopy, 16, z);
  15.     inc(z, TCheckBox(FWOArray[o]).Height + CGap);
  16.   end;
  17.   inc(y, gbDirectoryPropertiesToCopy.Height + CGap);
  18.  

Why groupboxes are cuted in middle?
Lazarus v. 4.99. FPC v. 3.3.1. Windows 11

wp

  • Hero Member
  • *****
  • Posts: 13412
Re: TGroupBox.AutoSize is broken?
« Reply #8 on: August 10, 2025, 08:45:53 pm »
Where is this code called? In the form's OnCreate? This usually is too early to rely on the size of auto-sized controls because AutoSizing occurs later. The best way to keep the 2nd groupbox below the 1st one, at a given distance, is to use anchoring (https://wiki.freepascal.org/Anchor_Sides).

LemonParty

  • Sr. Member
  • ****
  • Posts: 415
Re: TGroupBox.AutoSize is broken?
« Reply #9 on: August 10, 2025, 09:20:40 pm »
Yes, called from OnCreate. I moved it to OnShow and still cuted in half.
Lazarus v. 4.99. FPC v. 3.3.1. Windows 11

wp

  • Hero Member
  • *****
  • Posts: 13412
Re: TGroupBox.AutoSize is broken?
« Reply #10 on: August 10, 2025, 11:53:41 pm »
Manually calculating control positions when Autosizing and LCLscaling are involved is very difficult... Use the helpers that the LCL gives you:
  • Anchoring: Use the AnchorSidesLeft/Top/Right/Bottom properties and their subproperties Control and Side to attach controls to each other. At designtime you have the AnchorEditor, at runtime you must call these methods yourself. Read and understand the article that I linked in the previous post.
  • ChildSizing: Made for exactly this purpose, and in fact it is used in TCheckGroup to align the checkboxes in there (BTW: Why don't you use TCheckGroup?): https://wiki.freepascal.org/Autosize_/_Layout#Rows,_columns_and_lines
The attached demo uses ChildSizing to position the checkboxes within the groupboxes, and Anchoring to position the groupboxes relative to each other.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12195
  • Debugger - SynEdit - and more
    • wiki
Re: TGroupBox.AutoSize is broken?
« Reply #11 on: August 11, 2025, 01:11:37 am »
Yes, called from OnCreate. I moved it to OnShow and still cuted in half.

There was a very recent fix, that deals with **some** of those effects, when you have
- a form loaded from lfm, that will be scaled
- then do stuff in the constructor (resize some stuff)
- then show the form.

So not 100% your case, but close.

Currently, the scaling in the above case is done in "AfterConstruction" => So whatever you do in Form.Create is unscaled.

If your form was saved with DPI=192, then you add something in Create, and then that addition will be handled like it was put there for 192 dpi. So if that form is then show at a different dpi, then the addition is scaled too. (At least if I remember correctly).

But, in cases like that, autosizing may have gotten broken.

See commits
09e453027f3a521ce7f80ccba897f8d281fab39d
0da95ac806052c9f7d9f5c20db1a9974074dd010
4cca89e05f3fcc0d7f801a6ce602639fd3c1d1f3
c9a4d44950d87108b2ba51c76b960071d3d60f16

This is only changed in 4.99 (trunk).


I haven't tested any of your examples / late now / too tired.

 

TinyPortal © 2005-2018