Recent

Author Topic: TButton size??  (Read 7630 times)

garlar27

  • Hero Member
  • *****
  • Posts: 652
TButton size??
« on: May 12, 2011, 10:00:52 pm »
I'm clueless and hope someone could help me with this one:

   I Have a form which has a public method which receives a string and an array of string. The method creates as many buttons as elements array have. Everything works fine.
   Then I wanted have all buttons with the same width: the width of the button with the longest caption.

   So I did this:
Code: Pascal  [Select][+][-]
  1. {_________________________________________________________________ ButtonClick }
  2. procedure TFormMensaje.ButtonClick(Sender: TObject);
  3. var
  4.    Msj: string;
  5. begin
  6.    if Sender is TButton then begin
  7.       FResponse := (Sender as TButton).Caption; // property FResponse: string;
  8.    end;
  9. end; {<--- ButtonClick }
  10.  
  11. function TFormMessage.ShowMsg(const Mssg: string; const BtnLst: array of string): string;
  12. var
  13.    i, TheLonger: Integer;
  14.    B: TButton;
  15. begin
  16.    Result := '';
  17.    TheLonger := 0;
  18.    SetLength(FBtnLst, High(BtnLst+1)); // property: FBtnLst Array of TButton
  19.  
  20.    for i := 0 to High(BtnLst) do begin
  21.       B := TButton.Create(Self);
  22.       FBtnLst[i] := B;
  23.       { Here I set properties like parent, position, etc. }
  24.       B.OnClick := @ButtonClick;
  25.       B.Autosize := True;
  26.       B.Caption := BtnLst[i];
  27.       TheLonger := Max(TheLonger, B.With);
  28.    end;
  29.  
  30.    for i := 0 to High(FBtnLst) do begin
  31.       FBtnLst[i].AutoSize := FALSE;
  32.       FBtnLst[i].Width := TheLongest;
  33.    end;
  34.  
  35.    ShowModal;
  36.  
  37.    Result := FResponse;
  38. end;
  39.  

   The problem with that code is that it always set the width to 75 and not the "real" button's width.

   I did a workaround by doing this
Code: Pascal  [Select][+][-]
  1.    //.....
  2.    TheLongest := Max(TheLongest, Canvas.TextExtent(B.Caption).cx);
  3.    //...
  4.  
  5.    //...
  6.       FBtnLst[i].Width := TheLongest + AN_ARBITRARY_MARGIN_CONSTANT;
  7.    //...
  8.  
  9.  

   It works but I don't like it because different OS / Themes might have or need different margins.

   So here comes my question: Does anybody knows a better way to do it?

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: TButton size??
« Reply #1 on: May 12, 2011, 11:52:18 pm »
I can't see TheLongest declared.
Code: [Select]
for i := 0 to High(BtnLst) do begin 
      B := TButton.Create(Self); 
      FBtnLst<i> := B; 
      { Here I set properties like parent, position, etc. } 
      B.OnClick := @ButtonClick; 
      B.Autosize := True; 
      B.Caption := BtnLst<i>; 
      TheLonger := Max(TheLonger, B.With); 
   end; 
 
   for i := 0 to High(FBtnLst) do begin 
      FBtnLst<i>.AutoSize := FALSE; 
      FBtnLst<i>.Width := TheLongest; 
   end; 
 
and probably you had to change [ ] to < > because of this forum.

Otherwise code seems good to me, maybe this problem is widgetset related. I tried to make TButton with AutoSize=True and to give it very long Caption and its size was immediately changed.

Oh, maybe I found problem now. You change buttons but the form is invisible. You call ShowModal at the end. IMO it is the reason.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

garlar27

  • Hero Member
  • *****
  • Posts: 652
Re: TButton size??
« Reply #2 on: May 13, 2011, 02:20:52 pm »
I can't see TheLongest declared.
Code: [Select]
for i := 0 to High(BtnLst) do begin 
      B := TButton.Create(Self); 
      FBtnLst<i> := B; 
      { Here I set properties like parent, position, etc. } 
      B.OnClick := @ButtonClick; 
      B.Autosize := True; 
      B.Caption := BtnLst<i>; 
      TheLonger := Max(TheLonger, B.With); 
   end; 
 
   for i := 0 to High(FBtnLst) do begin 
      FBtnLst<i>.AutoSize := FALSE; 
      FBtnLst<i>.Width := TheLongest; 
   end; 
 
and probably you had to change [ ] to < > because of this forum.
:-[
Yep, I have to watch my hands from typo "Longer" should be "Longest". And I forgot about that bracket thing...

Oh, maybe I found problem now. You change buttons but the form is invisible. You call ShowModal at the end. IMO it is the reason.

Exactly!! I realized that very quickly and placing the resizing code in FormShow didn't help. afterwards I tried to access properties and methods to get the size the button will have when painted tried with almost any thing that came to my head but I couldn't make it.

If possible I would like to adjust size before showing the form.

My work around is working but it might get me in trouble when using another theming or OS.

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: TButton size??
« Reply #3 on: May 13, 2011, 03:48:08 pm »
I think I got it. You need this:
Code: [Select]
procedure GetPreferredSize(var PreferredWidth, PreferredHeight: integer;
                               Raw: boolean = false;
                               WithThemeSpace: boolean = true); virtual;
Simply:
Code: [Select]
var w, h: Longint;
begin
...
Button.GetPreferredSize(w, h, false, true);
...
and you will have the right width in variable "w" even if the button is invisible and its size is not changed yet.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

garlar27

  • Hero Member
  • *****
  • Posts: 652
Re: TButton size??
« Reply #4 on: May 16, 2011, 05:21:31 pm »
I couldn't make it work :( maybe it's due to my old (Lazarus 0.9.28.2) or my OS (Ubuntu 9.10).

Code: [Select]
...
Button := TButton.Create(Self);
Button.Parent := Self;
Button.Autosize := True;
Button.Top := 0;
Button.Left := 0;
Button.Caption  := ACaption;
Button.GetPreferredSize(w, h, false, true);
// Here "w" and "h" values are zero

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: TButton size??
« Reply #5 on: May 16, 2011, 05:34:17 pm »
This works (Laz. 0.9.31 + Qt):
Code: [Select]
var w, h: LongInt;
   Butt: TButton;
begin
  Butt:=TButton.Create(self);
  with Butt do
    begin
      Butt.Parent:=self;
      Butt.Visible:=False;
      Butt.AutoSize:=False;  //regardless if it is False; or True;
      Butt.Caption:='Butt++++++++++++++++++++++';
      Butt.GetPreferredSize(w, h, false, true);
      Form1.Caption:=inttostr(Butt.Width)+' '+inttostr(w);
      Free;
    end;
Form title is: "75 186"
75 is the default width, 186
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

garlar27

  • Hero Member
  • *****
  • Posts: 652
Re: TButton size??
« Reply #6 on: May 16, 2011, 06:44:36 pm »
Thank you Blaazen.

I will try to test it on 0.9.30 + gtk.

I think I won't have problems.

 

TinyPortal © 2005-2018