Recent

Author Topic: Adding buttons to TToolBar from runtime  (Read 2095 times)

CM630

  • Hero Member
  • *****
  • Posts: 1081
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Adding buttons to TToolBar from runtime
« on: January 21, 2022, 07:53:04 am »
I am trying to add buttons to a TToolBar at runtime.
In the code below (also attached), if I uncomment AddButtons(ToolBar, ['1', '2', '3', '4', '5']); in
procedure TForm1.FormCreate(Sender: TObject); I get buttons ordered in the following way:
1  2  3  4  5

But if I uncomment only AddButtons(ToolBar, ['1', '2', '3', '4', '5']); in procedure TForm1.Button1Click(Sender: TObject); when I click Button 1 I get buttons ordered in the following way:
5  4  3  2  1

Am I doing something wrong or there is sth. wrong with Lazarus?

Code: Pascal  [Select][+][-]
  1.  
  2. unit Unit1;
  3.  
  4.  
  5. {$mode objfpc}{$H+}
  6.  
  7.  
  8. interface
  9.  
  10.  
  11. uses
  12.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ComCtrls, StdCtrls;
  13.  
  14.  
  15. type
  16.  
  17.  
  18.   { TForm1 }
  19.  
  20.  
  21.   TForm1 = class(TForm)
  22.     Button1: TButton;
  23.     ToolBar: TToolBar;
  24.     procedure Button1Click(Sender: TObject);
  25.     procedure FormCreate(Sender: TObject);
  26.   private
  27.  
  28.  
  29.   public
  30.  
  31.  
  32.   end;
  33.  
  34.  
  35. var
  36.   Form1: TForm1;
  37.  
  38.  
  39. implementation
  40.  
  41.  
  42. {$R *.lfm}
  43.  
  44.  
  45. { TForm1 }
  46.  
  47.  
  48. procedure AddButtons(ToolBar: TToolBar; const ButtonCaptions: array of String);
  49. var
  50.   i: integer;
  51. begin
  52.   for i := 0 to High(ButtonCaptions) do
  53.   begin
  54.     with TToolButton.Create(ToolBar) do
  55.     begin
  56.       Parent := ToolBar;
  57.       Caption := ButtonCaptions[i];
  58.       if (ButtonCaptions[i] = '|') then
  59.         Style := tbsSeparator
  60.       else
  61.         Style := tbsButton;
  62.       AutoSize := True;
  63.     end;
  64.   end;
  65. end;
  66.  
  67.  
  68. procedure TForm1.FormCreate(Sender: TObject);
  69. begin
  70.   ToolBar.ShowCaptions := True;
  71.   //AddButtons(ToolBar, ['1', '2', '3', '4', '5']);
  72. end;
  73.  
  74.  
  75. procedure TForm1.Button1Click(Sender: TObject);
  76. begin
  77.   //AddButtons(ToolBar, ['1', '2', '3', '4', '5']);
  78. end;
  79.  
  80.  
  81. end.
  82.  
  83.  
  84.  
« Last Edit: January 22, 2022, 05:38:09 pm by CM630 »
Лазар 3,2 32 bit (sometimes 64 bit); FPC3,2,2; rev: Lazarus_3_0 on Win10 64bit.

speter

  • Sr. Member
  • ****
  • Posts: 345
Re: Adding buttons to TToolBar from runtime
« Reply #1 on: January 21, 2022, 11:44:05 am »
I found the same result (Laz 2.2; Win 11).

One quick fix is to add
Code: Pascal  [Select][+][-]
  1. left := parent.width;
after line 62 (AutoSize := True;) in your code.

procedure AddButtons() is from https://lazarus-ccr.sourceforge.io/docs/lcl/comctrls/ttoolbar.buttons.html so (if others find the same behaviour) maybe the example should be tweaked.

cheers
S.

I climbed mighty mountains, and saw that they were actually tiny foothills. :)

CM630

  • Hero Member
  • *****
  • Posts: 1081
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Adding buttons to TToolBar from runtime
« Reply #2 on: January 21, 2022, 01:29:06 pm »
Thanks, it works.
Indeed, I have used the sample from https://lazarus-ccr.sourceforge.io/docs/lcl/comctrls/ttoolbar.buttons.html.
I have added the example in the wiki:
https://wiki.lazarus.freepascal.org/TToolBar#Example.
« Last Edit: January 21, 2022, 01:38:38 pm by CM630 »
Лазар 3,2 32 bit (sometimes 64 bit); FPC3,2,2; rev: Lazarus_3_0 on Win10 64bit.

wp

  • Hero Member
  • *****
  • Posts: 11854
Re: Adding buttons to TToolBar from runtime
« Reply #3 on: January 21, 2022, 01:55:06 pm »
I found the same result (Laz 2.2; Win 11).

One quick fix is to add
Code: Pascal  [Select][+][-]
  1. left := parent.width;
after line 62 (AutoSize := True;) in your code.
This does not help if the total width of all buttons is larger than the width of the toolbar; when the toolbar is filled the next buttons will be added in reverse order again. The fix also fails when the toolbar is vertical.

I think it would be better to reverse the order in which the buttons are added:
Code: Pascal  [Select][+][-]
  1. procedure AddButtons(ToolBar: TToolBar; const ButtonCaptions: array of String);
  2. var
  3.   i: integer;
  4. begin
  5.   for i := High(ButtonCaptions) downto 0 do  
  6.   begin
  7.     with TToolButton.Create(ToolBar) do
  8.     begin
  9.       Parent := ToolBar;
  10.       Caption := ButtonCaptions[i];
  11.       if (ButtonCaptions[i] = '|') then
  12.         Style := tbsSeparator
  13.       else
  14.         Style := tbsButton;
  15.       AutoSize := True;
  16.     end;
  17.   end;
  18. end;
  19.  

I am not sure, though, whether this behavious isn't a bug. IIRC there is a similar issue when a series of top-aligned controls are added to a parent - they always are in reverse order. Maybe this topic should be reported to the bug-tracker so that a developer can have a look.

CM630

  • Hero Member
  • *****
  • Posts: 1081
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Adding buttons to TToolBar from runtime
« Reply #4 on: January 21, 2022, 02:10:57 pm »
...I think it would be better to reverse the order in which the buttons are added:...
I was also thinking about that, but as seen from my example, sometimes the buttons are added from left to right, and sometimes they are added from right to left.
How is one to know what direction will be used, in order to select the proper adding order?

Maybe if s.o. could try it on Delphi, it would be clear what the expected behaviour is.
« Last Edit: January 21, 2022, 02:26:10 pm by CM630 »
Лазар 3,2 32 bit (sometimes 64 bit); FPC3,2,2; rev: Lazarus_3_0 on Win10 64bit.

 

TinyPortal © 2005-2018