unit LayoutButtons;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, StdCtrls;
type
TBtnRange = 1..6;
TBArray = array[TBtnRange] of TButton;
{ TForm1 }
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
FButtons: TBArray;
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
var
i: integer;
hw: TPoint;
function NewButton(anIdx: integer): TButton;
var
r, c: integer;
begin
r:=(anIdx-1) div 3;
c:=(anIdx-1) mod 3;
Result:=TButton.Create(Self);
Result.AutoSize:=False;
Result.Name:=Format('FButtons_%d',[anIdx]);
Result.SetBounds(c*hw.x-(c+1), r*hw.y-(r+1), hw.x, hw.y);
Result.Parent:=Self;
end;
function GetHW: TPoint;
begin
Result.x:=ClientWidth div 3;
Result.y:=ClientHeight div 2;
end;
begin
hw:=GetHW;
for i in TBtnRange do
FButtons[i]:=NewButton(i);
Height:=FButtons[High(TBtnRange)].BoundsRect.Bottom;
Width:=FButtons[High(TBtnRange)].BoundsRect.Right;
end;
end.
Interesting, I didn't noticed this before.But widgets in panel will not auto resize.
I have solution: remove all anchors of the button on the panel ( Anchors := [ ]; ) and resize the form a little.
In GTK there is "table's boxes", and in wxWidgets there is "wxGridSizer".
Is there same thing in LCL?
QuoteIn GTK there is "table's boxes", and in wxWidgets there is "wxGridSizer".
Is there same thing in LCL?
Not that I'm aware of.
Does this help?
http://wiki.lazarus.freepascal.org/Autosize_/_Layout
var
Form1: TForm1;
AutoZoom: array of array of real;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
var
i, j: integer;
begin
SetLength(AutoZoom, Self.ControlCount, 4);
for i := 0 to Self.ControlCount - 1 do
begin
AutoZoom[i][0] := Self.Controls[i].Top / Self.Height;
AutoZoom[i][1] := Self.Controls[i].Left / Self.Width;
AutoZoom[i][2] := Self.Controls[i].Width / Self.Width;
AutoZoom[i][3] := Self.Controls[i].Height / Self.Height;
end;
end;
procedure TForm1.FormResize(Sender: TObject);
var
i: integer;
begin
for i := 0 to Form1.ControlCount - 1 do
begin
Self.Controls[i].Top := Round(AutoZoom[i][0] * Self.Height);
Self.Controls[i].Left := Round(AutoZoom[i][1] * Self.Width);
Self.Controls[i].Width := Round(AutoZoom[i][2] * Self.Width);
Self.Controls[i].Height := Round(AutoZoom[i][3] * Self.Height);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
i: integer;
begin
LDummy.Left:=ClientWidth + 1;
SetLength(AutoZoom, Self.ControlCount, 4);
for i := 0 to Self.ControlCount - 1 do
begin
AutoZoom[i][0] := Self.Controls[i].Top / Self.Height;
AutoZoom[i][1] := Self.Controls[i].Left / Self.Width;
AutoZoom[i][2] := Self.Controls[i].Width / Self.Width;
AutoZoom[i][3] := Self.Controls[i].Height / Self.Height;
end;
end;
procedure TForm1.FormResize(Sender: TObject);
var
i, initialSize: integer;
procedure AdjustFontSize(aLabelHeight: integer);
var
textHeight: byte;
targetHeight: byte;
begin
textHeight:=LDummy.Canvas.TextHeight(LDummy.Caption);
targetHeight:=aLabelHeight;
if (textHeight < targetHeight) then
repeat
LDummy.Font.Size:=LDummy.Font.Size + 1;
textHeight:=LDummy.Canvas.TextHeight(LDummy.Caption);
until (textHeight in [Pred(targetHeight), targetHeight, Succ(targetHeight)])
else if (textHeight > targetHeight) then
repeat
LDummy.Font.Size:=LDummy.Font.Size - 1;
textHeight:=LDummy.Canvas.TextHeight(LDummy.Caption);
until (textHeight in [Pred(targetHeight), targetHeight, Succ(targetHeight)])
end;
begin
DisableAlign;
for i := 0 to Form1.ControlCount - 1 do
begin
Self.Controls[i].Top := Round(AutoZoom[i][0] * Self.Height);
Self.Controls[i].Left := Round(AutoZoom[i][1] * Self.Width);
Self.Controls[i].Width := Round(AutoZoom[i][2] * Self.Width);
Self.Controls[i].Height := Round(AutoZoom[i][3] * Self.Height);
end;
initialSize:=LDummy.Font.Size;
if (LDummy.Height <> LDummy.Canvas.TextHeight(LDummy.Caption)) then
AdjustFontSize(LDummy.Height);
if (LDummy.Font.Size <> initialSize) then
for i:=0 to form1.ControlCount-1 do
if (Controls[i] <> LDummy) then
Controls[i].Font.Size:=LDummy.Font.Size;
EnableAlign;
end;
A possible approach would be to drop a label somewhere on your form named LDummy, and then use some variation on the following:Code: [Select]procedure TForm1.FormCreate(Sender: TObject);
var
i: integer;
begin
LDummy.Left:=ClientWidth + 1;
SetLength(AutoZoom, Self.ControlCount, 4);
for i := 0 to Self.ControlCount - 1 do
begin
AutoZoom[i][0] := Self.Controls[i].Top / Self.Height;
AutoZoom[i][1] := Self.Controls[i].Left / Self.Width;
AutoZoom[i][2] := Self.Controls[i].Width / Self.Width;
AutoZoom[i][3] := Self.Controls[i].Height / Self.Height;
end;
end;
procedure TForm1.FormResize(Sender: TObject);
var
i, initialSize: integer;
procedure AdjustFontSize(aLabelHeight: integer);
var
textHeight: byte;
targetHeight: byte;
begin
textHeight:=LDummy.Canvas.TextHeight(LDummy.Caption);
targetHeight:=aLabelHeight;
if (textHeight < targetHeight) then
repeat
LDummy.Font.Size:=LDummy.Font.Size + 1;
textHeight:=LDummy.Canvas.TextHeight(LDummy.Caption);
until (textHeight in [Pred(targetHeight), targetHeight, Succ(targetHeight)])
else if (textHeight > targetHeight) then
repeat
LDummy.Font.Size:=LDummy.Font.Size - 1;
textHeight:=LDummy.Canvas.TextHeight(LDummy.Caption);
until (textHeight in [Pred(targetHeight), targetHeight, Succ(targetHeight)])
end;
begin
DisableAlign;
for i := 0 to Form1.ControlCount - 1 do
begin
Self.Controls[i].Top := Round(AutoZoom[i][0] * Self.Height);
Self.Controls[i].Left := Round(AutoZoom[i][1] * Self.Width);
Self.Controls[i].Width := Round(AutoZoom[i][2] * Self.Width);
Self.Controls[i].Height := Round(AutoZoom[i][3] * Self.Height);
end;
initialSize:=LDummy.Font.Size;
if (LDummy.Height <> LDummy.Canvas.TextHeight(LDummy.Caption)) then
AdjustFontSize(LDummy.Height);
if (LDummy.Font.Size <> initialSize) then
for i:=0 to form1.ControlCount-1 do
if (Controls[i] <> LDummy) then
Controls[i].Font.Size:=LDummy.Font.Size;
EnableAlign;
end;
var
Form1: TForm1;
AutoZoom: array of array of real;
FormAspect: real;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
var
i, j: integer;
begin
FormAspect := Self.Width / Self.Height;
SetLength(AutoZoom, Self.ControlCount, 6);
for i := 0 to Self.ControlCount - 1 do
begin
AutoZoom[i][0] := Self.Controls[i].Top / Self.Height;
AutoZoom[i][1] := Self.Controls[i].Left / Self.Width;
AutoZoom[i][2] := Self.Controls[i].Width / Self.Width;
AutoZoom[i][3] := Self.Controls[i].Height / Self.Height;
if Self.Controls[i].Font.Height = 0 then
Self.Controls[i].Font.Height := 24;
AutoZoom[i][4] := Self.Controls[i].Font.Height / Self.Width;
AutoZoom[i][5] := Self.Controls[i].Font.Height / Self.Height;
end;
end;
procedure TForm1.FormResize(Sender: TObject);
var
i: integer;
begin
for i := 0 to Form1.ControlCount - 1 do
begin
Self.Controls[i].Top := Round(AutoZoom[i][0] * Self.Height);
Self.Controls[i].Left := Round(AutoZoom[i][1] * Self.Width);
Self.Controls[i].Width := Round(AutoZoom[i][2] * Self.Width);
Self.Controls[i].Height := Round(AutoZoom[i][3] * Self.Height);
if Self.Width / Self.Height < FormAspect then
Self.Controls[i].Font.Height := Round(AutoZoom[i][4] * Self.Width)
else
Self.Controls[i].Font.Height := Round(AutoZoom[i][4] * Self.Height);
end;
end;
A possible approach would be to drop a label somewhere on your form named LDummy, and then use some variation on the following:Code: [Select]procedure TForm1.FormCreate(Sender: TObject);
var
i: integer;
begin
LDummy.Left:=ClientWidth + 1;
SetLength(AutoZoom, Self.ControlCount, 4);
for i := 0 to Self.ControlCount - 1 do
begin
AutoZoom[i][0] := Self.Controls[i].Top / Self.Height;
AutoZoom[i][1] := Self.Controls[i].Left / Self.Width;
AutoZoom[i][2] := Self.Controls[i].Width / Self.Width;
AutoZoom[i][3] := Self.Controls[i].Height / Self.Height;
end;
end;
procedure TForm1.FormResize(Sender: TObject);
var
i, initialSize: integer;
procedure AdjustFontSize(aLabelHeight: integer);
var
textHeight: byte;
targetHeight: byte;
begin
textHeight:=LDummy.Canvas.TextHeight(LDummy.Caption);
targetHeight:=aLabelHeight;
if (textHeight < targetHeight) then
repeat
LDummy.Font.Size:=LDummy.Font.Size + 1;
textHeight:=LDummy.Canvas.TextHeight(LDummy.Caption);
until (textHeight in [Pred(targetHeight), targetHeight, Succ(targetHeight)])
else if (textHeight > targetHeight) then
repeat
LDummy.Font.Size:=LDummy.Font.Size - 1;
textHeight:=LDummy.Canvas.TextHeight(LDummy.Caption);
until (textHeight in [Pred(targetHeight), targetHeight, Succ(targetHeight)])
end;
begin
DisableAlign;
for i := 0 to Form1.ControlCount - 1 do
begin
Self.Controls[i].Top := Round(AutoZoom[i][0] * Self.Height);
Self.Controls[i].Left := Round(AutoZoom[i][1] * Self.Width);
Self.Controls[i].Width := Round(AutoZoom[i][2] * Self.Width);
Self.Controls[i].Height := Round(AutoZoom[i][3] * Self.Height);
end;
initialSize:=LDummy.Font.Size;
if (LDummy.Height <> LDummy.Canvas.TextHeight(LDummy.Caption)) then
AdjustFontSize(LDummy.Height);
if (LDummy.Font.Size <> initialSize) then
for i:=0 to form1.ControlCount-1 do
if (Controls[i] <> LDummy) then
Controls[i].Font.Size:=LDummy.Font.Size;
EnableAlign;
end;
Sorry, I don't understand your code.
It doesn't work for me.
The font size keep growing when I resize the form, no matter the form is big or small.
And why call DisableAlign? Is that matter?
BTW, I think this way is easier.
@dsw1Code: [Select]var
Form1: TForm1;
AutoZoom: array of array of real;
FormAspect: real;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
var
i, j: integer;
begin
FormAspect := Self.Width / Self.Height;
SetLength(AutoZoom, Self.ControlCount, 6);
for i := 0 to Self.ControlCount - 1 do
begin
AutoZoom[i][0] := Self.Controls[i].Top / Self.Height;
AutoZoom[i][1] := Self.Controls[i].Left / Self.Width;
AutoZoom[i][2] := Self.Controls[i].Width / Self.Width;
AutoZoom[i][3] := Self.Controls[i].Height / Self.Height;
if Self.Controls[i].Font.Height = 0 then
Self.Controls[i].Font.Height := 24;
AutoZoom[i][4] := Self.Controls[i].Font.Height / Self.Width;
AutoZoom[i][5] := Self.Controls[i].Font.Height / Self.Height;
end;
end;
procedure TForm1.FormResize(Sender: TObject);
var
i: integer;
begin
for i := 0 to Form1.ControlCount - 1 do
begin
Self.Controls[i].Top := Round(AutoZoom[i][0] * Self.Height);
Self.Controls[i].Left := Round(AutoZoom[i][1] * Self.Width);
Self.Controls[i].Width := Round(AutoZoom[i][2] * Self.Width);
Self.Controls[i].Height := Round(AutoZoom[i][3] * Self.Height);
if Self.Width / Self.Height < FormAspect then
Self.Controls[i].Font.Height := Round(AutoZoom[i][4] * Self.Width)
else
Self.Controls[i].Font.Height := Round(AutoZoom[i][4] * Self.Height);
end;
end;