Forum > Designer

[SOLVED] anchors auto resize

<< < (3/4) > >>

mercury:

--- Quote from: Mike.Cornflake on February 18, 2015, 07:42:45 am ---
--- Quote ---In GTK there is "table's boxes", and in wxWidgets there is "wxGridSizer".
Is there same thing in LCL?
--- End quote ---

Not that I'm aware of.

Does this help?
http://wiki.lazarus.freepascal.org/Autosize_/_Layout

--- End quote ---

Seems LCL doesn't provide a way like "table's boxes" which GTK does.

But I find a way to do this.

--- Code: ---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;


--- End code ---

Thank you.

dsw1:
I used the code and it works very good to resize my form but I am struggling to resize fonts.
Any idea's on how this can be done?

howardpc:
A possible approach would be to drop a label somewhere on your form named LDummy, and then use some variation on the following:


--- Code: ---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;

--- End code ---

dsw1:
Thanks I can work with it.
I have forms containing different font sizes. I fixed that by calculating their relative size in relation to LDummy

mercury:

--- Quote from: howardpc on September 19, 2015, 07:28:21 pm ---A possible approach would be to drop a label somewhere on your form named LDummy, and then use some variation on the following:


--- Code: ---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;

--- End code ---

--- End quote ---

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.
@dsw1


--- Code: ---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;



--- End code ---

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version