Recent

Author Topic: Positioning invisible components BUG or Feature?  (Read 4849 times)

ps

  • Full Member
  • ***
  • Posts: 136
    • CSS
Positioning invisible components BUG or Feature?
« on: September 19, 2016, 03:09:13 pm »
Why is diference between:

Code for:
Code: Pascal  [Select][+][-]
  1. MainPanel.Visible := False;
  2. for I := 0 to 10 do begin
  3.   SubPanel := TPanel.Create(Self);
  4.   SubPanel.Parent := MainPanel;
  5.   SubPanel.Align := alTop;
  6.   SubPanel.Top := 20000;
  7.   SubPanel.Height := 20;
  8.   SubPanel.Caption := 'Panel number: ' + IntToStr(I);
  9. end;
  10. MainPanel.Visible := True;
Result is:

Panel number: 10
Panel number: 9
Panel number: 8
...
Panel number: 1

But for visible MainPanel.Visible := True; (same code). Result is correct:

Panel number: 1
Panel number: 2
...
Panel number: 10

Same problem is when creating components on form (for ex. OnCreate event); Under delphi both methods works same.
Lazarus 1.6 FPC 3.0.0, Windows 32/64 bit.
Small simple CSS/box model implementation: https://github.com/pst2d/csscontrols/tree/dev

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Positioning invisible components BUG or Feature?
« Reply #1 on: September 19, 2016, 05:15:06 pm »
This is a pseudo-problem. There is no reason why the LCL should be Delphi-compatible in these sorts of implementation details.
If it is a problem to you, simply alter your code to something like:
Code: Pascal  [Select][+][-]
  1. MainPanel.Visible := False;
  2.     for I := 0 to 10 do begin
  3.       SubPanel := TPanel.Create(Self);
  4.       SubPanel.Parent := MainPanel;
  5.       SubPanel.Align := alTop;
  6.       SubPanel.Top := I; // < - - - note the change here
  7.       SubPanel.Height := 20;
  8.       SubPanel.Caption := 'Panel number: ' + IntToStr(I);
  9.     end;
  10.   MainPanel.Visible := True;    

ps

  • Full Member
  • ***
  • Posts: 136
    • CSS
Re: Positioning invisible components BUG or Feature?
« Reply #2 on: September 19, 2016, 06:36:43 pm »
I'm trying Delphi only for test if this is feature. My problem is there is diference between visible and non-visible controls.
Your solution don't work for me because in real code I have many BorderSpacing etc. so many calculation will be needed to fix this problem. And creating controls with Visible is slow.
Small simple CSS/box model implementation: https://github.com/pst2d/csscontrols/tree/dev

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Positioning invisible components BUG or Feature?
« Reply #3 on: September 19, 2016, 07:03:42 pm »
In general it is not wise to parent child controls to invisible containers, and then later reset the visibility, because the invisible->visible change can have differing side-effects on different widgetsets.
In the LCL it is better to set all properties needed except the Parent.
Then set the Parent(s) as the very last step in initialisation.
Delphi does not allow this (or did not allow it, perhaps things have changed). This LCL feature alone usually saves milliseconds if not seconds with large complex forms.
Also using the Align property for multiple child controls is usually a sign of poor design. It is usually much better to use Anchors and ChildSizing for layouts involving more than one or two child controls.

Can you show compilable code that demonstrates a real problem that you have?
« Last Edit: September 19, 2016, 07:05:37 pm by howardpc »

Thaddy

  • Hero Member
  • *****
  • Posts: 14369
  • Sensorship about opinions does not belong here.
Re: Positioning invisible components BUG or Feature?
« Reply #4 on: September 19, 2016, 07:38:43 pm »
Easy:
Form1, Mainpanel, subpanels.
Subpanel one contains an array of buttons.
Created at design time, or visible( the latter only on windows, a second panel will be below the ftrst one.
Created in a loop it behaves different. That's a bug. Align := caTop forgets to calculate its proper position relative to the other controls.

I mean that: it is a proper bug. On linux it is always the other way around creted at runtime. So at least there the bug is consistently different from design time.
I can confirm Delphi has exactly the same behavior at runtime, visible or not visible, and at runtime, visible or not visible.

And this is absolutely not implementation detail. Nor is it a feature nor has it much to do with speed.
It is also not a compiler induces optimization (loop reversal). Its a BUG. The LCL should respect intention in its implementation. IOW it should respect creation order as drawing order, it should respect toggling align:= false or true as well.The creatiopn  order is readily available in the Children list. The paint order should rely on that
Here the intention is to keep the same order as expected when designing by hand.
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Positioning invisible components BUG or Feature?
« Reply #5 on: September 19, 2016, 08:04:20 pm »
Your solution don't work for me because in real code I have many BorderSpacing etc. so many calculation will be needed to fix this problem. And creating controls with Visible is slow.

The  BorderSpacing value for each child control has no effect on the layout positioning order. No extra calculations are needed at all.
See for yourself, add a line like this:
Code: Pascal  [Select][+][-]
  1. for I := 0 to 10 do begin
  2.       SubPanel := TPanel.Create(Self);
  3.       subPanel.BorderSpacing.Around:=Random(12); // - - > add this line
  4.       SubPanel.Parent := MainPanel;
  5.       SubPanel.Align := alTop;
  6.       SubPanel.Top := I;
  7.       SubPanel.Height := 20;
  8.       SubPanel.Caption := 'Panel number: ' + IntToStr(I);
  9.     end;  

ps

  • Full Member
  • ***
  • Posts: 136
    • CSS
Re: Positioning invisible components BUG or Feature?
« Reply #6 on: September 26, 2016, 02:58:30 pm »
Thank's for your solution, your code work (without random BorderSpacing , due to random AV (loop detection)). But there is still diference between visible and non visible (order is changed). But I can live with this if this is not bug.

ChildSizing is very interesting for me, but I can't find solution to have different height for controls.
Small simple CSS/box model implementation: https://github.com/pst2d/csscontrols/tree/dev

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Positioning invisible components BUG or Feature?
« Reply #7 on: September 26, 2016, 04:09:12 pm »
Thaddy, who knows far more than me about these things, considers the visible/invisible ordering difference a bug.
In which case the code I gave must be considered a workaround. I see no sign of this 'bug' getting fixed, so I have tended to regard it as an LCL feature.
Since I don't use Delphi I'm generally unaware of incompatabilities between Lazarus and Delphi.

Childsizing as far as I know is designed to place controls in a simple grid pattern. So, no, it does not provide for controls of different height.
To achieve such complex layouts requires hand-coding. And often what works on one widgetset then behaves slightly differently on another. Getting flawless GUI layouts crossplatform across different widgetsets/OSs with differing screen dpi settings and different themes and window managers can be a daunting task.

 

TinyPortal © 2005-2018