Recent

Author Topic: Magnify/Fontsize changing, apply to all elements and realign  (Read 739 times)

TCH

  • Sr. Member
  • ****
  • Posts: 275
    • Oldschool computer
Magnify/Fontsize changing, apply to all elements and realign
« on: April 19, 2022, 02:02:18 pm »
Is there a simple way to magnify elements (size, fontsize) on the form without screwing up the alignments, distances, etc.?

I came up with this, but it does not work properly, only "roughly".
Code: Pascal  [Select][+][-]
  1. procedure AddToComponentsGeometry(Form: TForm; WinControl: TWinControl);
  2. var
  3.         c, j, cd: integer;
  4.         EWinControl: TWinControl;
  5. begin
  6.         c := Length(ComponentsGeometry);
  7.         SetLength(ComponentsGeometry, c + 1);
  8.         ComponentsGeometry[c].WinControl := WinControl;
  9.         ComponentsGeometry[c].TopWinControl := nil;
  10.         ComponentsGeometry[c].LeftWinControl := nil;
  11.         ComponentsGeometry[c].TopDistance := $7fffffff;
  12.         ComponentsGeometry[c].LeftDistance := $7fffffff;
  13.         ComponentsGeometry[c].Top := WinControl.Top;
  14.         ComponentsGeometry[c].Left := WinControl.Left;
  15.         ComponentsGeometry[c].Width := WinControl.Width;
  16.         ComponentsGeometry[c].Height := WinControl.Height;
  17.         for j := 0 to Form.ComponentCount - 1 do
  18.         begin
  19.                 if (Form.Components[j] is TWinControl) then
  20.                 begin
  21.                         EWinControl := Form.Components[j] as TWinControl;
  22.                         cd := WinControl.Top - (EWinControl.Top + EWinControl.Height);
  23.                         if ((cd >= 0) and (cd < ComponentsGeometry[c].TopDistance)) then
  24.                         begin
  25.                                 ComponentsGeometry[c].TopWinControl := EWinControl;
  26.                                 ComponentsGeometry[c].TopDistance := cd;
  27.                         end;
  28.                         cd := WinControl.Left - (EWinControl.Left + EWinControl.Width);
  29.                         if ((cd >= 0) and (cd < ComponentsGeometry[c].LeftDistance)) then
  30.                         begin
  31.                                 ComponentsGeometry[c].LeftWinControl := EWinControl;
  32.                                 ComponentsGeometry[c].LeftDistance := cd;
  33.                         end;
  34.                 end;
  35.         end;
  36. end;
  37.  
  38. procedure StoreComponentsGeometry;
  39. var i, j: integer;
  40. begin
  41.         SetLength(ComponentsGeometry, 0);
  42.         for i := 0 to Screen.FormCount - 1 do
  43.         begin
  44.                 for j := 0 to Screen.Forms[i].ComponentCount - 1 do
  45.                 begin
  46.                         if (Screen.Forms[i].Components[j] is TWinControl) then
  47.                         begin
  48.                                 AddToComponentsGeometry(Screen.Forms[i], Screen.Forms[i].Components[j] as TWinControl);
  49.                         end;
  50.                 end;
  51.         end;
  52. end;
  53.  
  54. procedure AlignItems;
  55. var
  56.         i, j, c, d, Right, Bottom: integer;
  57.         WinControl: TWinControl;
  58. begin
  59.         for i := 0 to Screen.FormCount - 1 do
  60.         begin
  61.                 d := Screen.Forms[i].Font.Size - 10;
  62.                 for j := 0 to Screen.Forms[i].ComponentCount - 1 do
  63.                 begin
  64.                         if (Screen.Forms[i].Components[j] is TWinControl) then
  65.                         begin
  66.                                 WinControl := Screen.Forms[i].Components[j] as TWinControl;
  67.                                 c := 0; // silences warning
  68.                                 for c := 0 to length(ComponentsGeometry) - 1 do
  69.                                 begin
  70.                                         if (WinControl = ComponentsGeometry[c].WinControl) then
  71.                                         begin
  72.                                                 break;
  73.                                         end;
  74.                                 end;
  75.                                 if (c < length(ComponentsGeometry)) then
  76.                                 begin
  77.                                         if (not WinControl.AutoSize) then
  78.                                         begin
  79.                                                 WinControl.Width := ComponentsGeometry[c].Width + d;
  80.                                                 WinControl.Height := ComponentsGeometry[c].Height + d;
  81.                                         end;
  82.                                         if (ComponentsGeometry[c].TopWinControl <> nil) then
  83.                                         begin
  84.                                                 WinControl.Top := ComponentsGeometry[c].TopWinControl.Top + ComponentsGeometry[c].TopWinControl.Height + ComponentsGeometry[c].TopDistance;
  85.                                         end;
  86.                                         if (ComponentsGeometry[c].LeftWinControl <> nil) then
  87.                                         begin
  88.                                                 WinControl.Left := ComponentsGeometry[c].LeftWinControl.Left + ComponentsGeometry[c].LeftWinControl.Width + ComponentsGeometry[c].LeftDistance;
  89.                                         end;
  90.                                 end;
  91.                         end;
  92.                 end;
  93.         end;
  94.         for i := 0 to Screen.FormCount - 1 do
  95.         begin
  96.                 Right := 0;
  97.                 Bottom := 0;
  98.                 for j := 0 to Screen.Forms[i].ComponentCount - 1 do
  99.                 begin
  100.                         if (Screen.Forms[i].Components[j] is TWinControl) then
  101.                         begin
  102.                                 WinControl := Screen.Forms[i].Components[j] as TWinControl;
  103.                                 c :=WinControl.Top + WinControl.Height;
  104.                                 if (c > Bottom) then
  105.                                 begin
  106.                                         Bottom := c;
  107.                                 end;
  108.                                 c :=WinControl.Left + WinControl.Width;
  109.                                 if (c > Right) then
  110.                                 begin
  111.                                         Right := c;
  112.                                 end;
  113.                         end;
  114.                 end;
  115.                 Screen.Forms[i].Width := Right;
  116.                 Screen.Forms[i].Height := Bottom;
  117.         end;
  118. end;
  119.  
  120. procedure ApplyFontSize;
  121. var i: integer;
  122. begin
  123.         if (FontSize < 1) then
  124.         begin
  125.                 FontSize := 1;
  126.         end
  127.         else
  128.         begin
  129.                 if (FontSize > 24) then
  130.                 begin
  131.                         FontSize := 24;
  132.                 end;
  133.         end;
  134.         for i := 0 to Screen.FormCount - 1 do
  135.         begin
  136.                 Screen.Forms[i].Font.Size := FontSize;
  137.         end;
  138.         AlignItems;
  139. end;
  140.  
  141. procedure StepFontSize(step: LongInt);
  142. begin
  143.         FontSize := LongWord(LongInt(FontSize) + step);
  144.         ApplyFontSize;
  145. end;
Also i tried to use magnifying instead of font size (as in having a multiplier value for original sizes), but it gave even weaker results...
« Last Edit: April 19, 2022, 02:04:55 pm by TCH »

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Magnify/Fontsize changing, apply to all elements and realign
« Reply #1 on: April 19, 2022, 02:35:14 pm »
Is there a simple way to magnify elements (size, fontsize) on the form without screwing up the alignments, distances, etc.?
Layout that survives fundamental changes to sizes of form elements is never simple, especially if it needs to be cross-platform and multilingual.
The LCL's autosize/preferred-size mechanisms combined with LCL anchoring (and maybe childsizing) is about the best "simple" compromise I've seen in the Object Pascal world.
It is not perfect, but you'll probably find it works better than any roll-your-own solutions (depending on how complex and adaptable your particular layout needs to be).

 

TinyPortal © 2005-2018