Recent

Author Topic: Hidden controls inside of a flow panel still occupy space  (Read 1042 times)

Joanna

  • Sr. Member
  • ****
  • Posts: 392
Hidden controls inside of a flow panel still occupy space
« on: February 09, 2023, 02:44:05 am »
I don't know if this is intended or not but the hidden controls inside of a flowpanel still occupy space and cause the flow panel to be bloated with extra blank space.

My current workaround is to remove invisible controls from the flovwpanel and only have flowpanel as parent for visible controls.

Perhaps the code for the tflowpanel needs some reworking to take visibility into account when sizing ?
Joanna, Curator of #fpc channel on Libera.
Come chat on IRC .. https://libera.chat/guides/
IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channels  #fpc  #pascal 
Private Message me if you want to be added to invite list, otherwise type /msg nickserv help register to get started

Handoko

  • Hero Member
  • *****
  • Posts: 4837
  • My goal: build my own game engine using Lazarus
Re: Hidden controls inside of a flow panel still occupy space
« Reply #1 on: February 09, 2023, 05:03:07 am »
Tested on Lazarus 2.3.0 GTK2 on Ubuntu Mate 64-bit.

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, ExtCtrls, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Button1: TButton;
  16.     Button2: TButton;
  17.     Button3: TButton;
  18.     Button4: TButton;
  19.     FlowPanel1: TFlowPanel;
  20.     procedure Button4Click(Sender: TObject);
  21.     procedure FormCreate(Sender: TObject);
  22.   end;
  23.  
  24. var
  25.   Form1: TForm1;
  26.  
  27. implementation
  28.  
  29. {$R *.lfm}
  30.  
  31. { TForm1 }
  32.  
  33. procedure TForm1.Button4Click(Sender: TObject);
  34. begin
  35.   Button2.Visible := False;
  36. end;
  37.  
  38. procedure TForm1.FormCreate(Sender: TObject);
  39. begin
  40.   FlowPanel1.Anchors := [akLeft] + [akRight] + [akTop] + [akBottom];
  41. end;
  42.  
  43. end.

After clicking the "Click Me" button, the Button2 will be hidden. It's working good on my test, or did I misunderstand what you meant?

Joanna

  • Sr. Member
  • ****
  • Posts: 392
Re: Hidden controls inside of a flow panel still occupy space
« Reply #2 on: February 09, 2023, 07:06:51 am »
have you tried making the flow panel a distinct color like clred and then trying to get the flow panel elements to be on one row? and then hiding one ?
 when i do this the flow panel is wider than necessary because it is accommodating
the hidden control.
what does it look like if you hide button2?
« Last Edit: February 09, 2023, 07:09:23 am by Joanna »
Joanna, Curator of #fpc channel on Libera.
Come chat on IRC .. https://libera.chat/guides/
IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channels  #fpc  #pascal 
Private Message me if you want to be added to invite list, otherwise type /msg nickserv help register to get started

Handoko

  • Hero Member
  • *****
  • Posts: 4837
  • My goal: build my own game engine using Lazarus
Re: Hidden controls inside of a flow panel still occupy space
« Reply #3 on: February 09, 2023, 09:23:17 am »
Sorry, I couldn't reproduce it or fully understood what you said. Please provide a demo that shows the problem or at least modify the code:

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, ExtCtrls, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     btnClickMe: TButton;
  16.     FlowPanel1: TFlowPanel;
  17.     procedure btnClickMeClick(Sender: TObject);
  18.     procedure FormCreate(Sender: TObject);
  19.   private
  20.     FTarget: TButton;
  21.   end;
  22.  
  23. var
  24.   Form1: TForm1;
  25.  
  26. implementation
  27.  
  28. {$R *.lfm}
  29.  
  30. { TForm1 }
  31.  
  32. procedure TForm1.btnClickMeClick(Sender: TObject);
  33. begin
  34.   FTarget.Visible  := False;
  35. end;
  36.  
  37. procedure TForm1.FormCreate(Sender: TObject);
  38. var
  39.   Button: TButton;
  40.   i:      Integer;
  41. begin
  42.   Constraints.MinHeight := 300;
  43.   Constraints.MaxHeight := 300;
  44.   FlowPanel1.Anchors    := [akLeft] + [akRight] + [akTop] + [akBottom];
  45.   FlowPanel1.Color      := clRed;
  46.   for i := 0 to 20 do
  47.   begin
  48.     Button         := TButton.Create(FlowPanel1);
  49.     Button.Parent  := FlowPanel1;
  50.     Button.Caption := i.ToString;
  51.     Button.Color   := $FF00AA + i * $BFF;
  52.     if i = 6 then
  53.     begin
  54.       Button.Color := $00FF00;
  55.       FTarget      := Button;
  56.     end;
  57.   end;
  58. end;
  59.  
  60. end.

Note: TButton.Color is not supported on Windows.
« Last Edit: February 09, 2023, 09:26:08 am by Handoko »

Joanna

  • Sr. Member
  • ****
  • Posts: 392
Re: Hidden controls inside of a flow panel still occupy space
« Reply #4 on: February 09, 2023, 11:59:38 am »
Thanks for trying to help , what happens if you have just 4 buttons and try to have the flow panel fit the buttons without extra space on one line then hide one of the buttons?

Also your picture shows a lot of extra space under the buttons. Are you able to have flowpanel fit around buttons without the blank area underneath?

I use tcdbuttons so I can control color  8)
« Last Edit: February 09, 2023, 12:22:19 pm by Joanna »
Joanna, Curator of #fpc channel on Libera.
Come chat on IRC .. https://libera.chat/guides/
IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channels  #fpc  #pascal 
Private Message me if you want to be added to invite list, otherwise type /msg nickserv help register to get started

Handoko

  • Hero Member
  • *****
  • Posts: 4837
  • My goal: build my own game engine using Lazarus
Re: Hidden controls inside of a flow panel still occupy space
« Reply #5 on: February 09, 2023, 12:14:58 pm »
I modified the source code in the reply #3:
- Line #46:   for i := 0 to 3 do
- Line #52:     if i = 2 then

Nothing weird happened, still worked as what it should be.

Also your picture shows a lot of extra space under the buttons. Are you able to have flowpanel fit around buttons without the blank area?

FlowPanel doesn't handle that issue. As the name suggests, it just makes all the items inside to flow to stick together. I haven't tried but if I want, I think I can to make all the items to fit properly without blank area but I would rather use a TPanel and write the code myself.

Joanna

  • Sr. Member
  • ****
  • Posts: 392
Re: Hidden controls inside of a flow panel still occupy space
« Reply #6 on: February 09, 2023, 12:25:38 pm »
Doesn’t flowpanel have some sort of autosize mechanism? So it can detect how much space it needs on bottom?
I use flowpanel inside a frame and constrain the frame to fit the flow panel but if the flowpanel contains hidden controls it still makes space where they would have been which is undesirable
« Last Edit: February 09, 2023, 12:31:53 pm by Joanna »
Joanna, Curator of #fpc channel on Libera.
Come chat on IRC .. https://libera.chat/guides/
IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channels  #fpc  #pascal 
Private Message me if you want to be added to invite list, otherwise type /msg nickserv help register to get started

Handoko

  • Hero Member
  • *****
  • Posts: 4837
  • My goal: build my own game engine using Lazarus
Re: Hidden controls inside of a flow panel still occupy space
« Reply #7 on: February 09, 2023, 12:37:24 pm »
I rarely use TFlowPanel and I also rarely use AutoSize. But for the similar purpose I ever used combination of:

- TPanel
- TSplitter
- Align := alClient
- Align := alTop or alButton.

And that worked.

Joanna

  • Sr. Member
  • ****
  • Posts: 392
Re: Hidden controls inside of a flow panel still occupy space
« Reply #8 on: February 09, 2023, 01:32:43 pm »
I use splitters and panels for some things but in this case I’m looking for a flowpanel that fits controls tightly without extra space on bottom. I will keep changing the parent of hidden controls I was just curious why I need to do this or if it will ever be fixed.
Joanna, Curator of #fpc channel on Libera.
Come chat on IRC .. https://libera.chat/guides/
IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channels  #fpc  #pascal 
Private Message me if you want to be added to invite list, otherwise type /msg nickserv help register to get started

Joanna

  • Sr. Member
  • ****
  • Posts: 392
Re: Hidden controls inside of a flow panel still occupy space
« Reply #9 on: February 09, 2023, 01:56:07 pm »
to be fair I'm doing something complicated .i have a frame with a flovwpanel that is inherited by another frame which creates frames inside the ancestor flow panel
Joanna, Curator of #fpc channel on Libera.
Come chat on IRC .. https://libera.chat/guides/
IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channels  #fpc  #pascal 
Private Message me if you want to be added to invite list, otherwise type /msg nickserv help register to get started

KodeZwerg

  • Hero Member
  • *****
  • Posts: 1404
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Hidden controls inside of a flow panel still occupy space
« Reply #10 on: February 09, 2023, 01:58:40 pm »
Can you attach a demo project to tinker a little? Sound like fun what you are doing/try to do
« Last Edit: Tomorrow at 31:76:97 by KodeZwerg »

wp

  • Hero Member
  • *****
  • Posts: 10875
Re: Hidden controls inside of a flow panel still occupy space
« Reply #11 on: February 09, 2023, 01:58:46 pm »
In my own tests (Windows, Linux), the TFlowPanel does rearrange the layout when a control is hidden. It does not resize the controls to fill the extra space at the bottom. Setting TFlowPanel.AutoSize to true arranges all controls in a single column, unless you specify an appropriate Constraints.MinWidth value for the FlowPanel.

Alternatively you could use a plain-old TPanel as containter and instruct the ChildSizing property to do the layout work:
  • Select the panel and go to its ChildSizing property.
  • Set Layout to cclLeftToRightThenTopToBottom
  • Set ControlsPerLine to the number of controls that you want to have in each row before following controls are wrapped into the nexxt row
  • Add your controls - they will be arranged automatically in rows (up to ControlsPerLine) and wrapped. Do not modify the Anchors (must be [akLeft, akTop], otherwise ChildSizing does not work).
  • Define the distance between the controls by means of HorizontalSpacing and VerticalSpacing. The border spacing is given by LeftRightSpacing and TopBottomSpacing.
  • Set the panel's AutoSize to true, and it will shrink to the total size of the automatically arranged controls.
  • On the other hand, you can keep Panel.AutoSize at false and force ChildSizing to resize the controls so that the total row width and column height fills the available space. For this you must set the panel.ChildSizing.EnlargeHorizontal, .EnlargeVertical, .ShrinkHorizontal, .ShrinkVertical to crsHomoenousChildResize. You have further control over the resizing processing when you do not apply this to all of these properites.
Practice work with ChildSizing in a dummy project because sometime the changes due to some settings cannot be reverted.

wiki documentation: https://wiki.freepascal.org/Autosize_/_Layout#Layout
« Last Edit: February 09, 2023, 02:01:02 pm by wp »

Joanna

  • Sr. Member
  • ****
  • Posts: 392
Re: Hidden controls inside of a flow panel still occupy space
« Reply #12 on: February 09, 2023, 02:38:49 pm »
Can you attach a demo project to tinker a little? Sound like fun what you are doing/try to do

My code is rather tightly coupled with inheritance. A brief description of what I’m doing is..
1. I have a base frame with a flowpanel->
2.a frame with Label and combobox inside flow panel ->
3. A frame with label and combobox which loads a list selected and unselected filtering Boolean Columns from an sqlite table->
4. A frame with a Boolean filter labeled combobox which creates frames with buttons to set a Boolean column to false in sqlite table.

The idea is to select one of the items in the combobox which generates an sql statement for example item ‘favorites’ generates ... select * from mytable where favorite = 1
‘Non favorite’ gives select * from mytable Where favorite = 0
I keep track of how many items in each column are selected using an array .

Only items that will generate a non empty dataset are permitted in combobox.

There are frames with button added to the ancestor flowpanel for for each Boolean column. Only button frames corresponding to Sqlite table columns with selected Values are visible. Hence the strange behavior of flowpanel being too tall if some are hidden. Which I solve by changing their parent to the frame itself.
 
I constrain the controls to fit their captions usually. I often have nested frames that are descendants of same flowpanel ancestor.
« Last Edit: February 09, 2023, 02:43:30 pm by Joanna »
Joanna, Curator of #fpc channel on Libera.
Come chat on IRC .. https://libera.chat/guides/
IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channels  #fpc  #pascal 
Private Message me if you want to be added to invite list, otherwise type /msg nickserv help register to get started

 

TinyPortal © 2005-2018