Issue #1482: experimental auto-arrangement of controls on session manager, due to much different height of controls

This commit is contained in:
Ansgar Becker
2025-03-23 13:48:35 +01:00
parent 8afe721e6f
commit 483a7ca386
2 changed files with 121 additions and 3 deletions

View File

@ -286,7 +286,11 @@ var
i: Integer; i: Integer;
ExeFiles: TStringList; ExeFiles: TStringList;
begin begin
ArrangeControls(tabSettings);
ArrangeControls(tabSSHtunnel);
ArrangeControls(tabAdvanced);
ArrangeControls(tabSSL);
ArrangeControls(tabStatistics);
Width := AppSettings.ReadInt(asSessionManagerWindowWidth); Width := AppSettings.ReadInt(asSessionManagerWindowWidth);
Height := AppSettings.ReadInt(asSessionManagerWindowHeight); Height := AppSettings.ReadInt(asSessionManagerWindowHeight);
Left := AppSettings.ReadInt(asSessionManagerWindowLeft, '', Left); Left := AppSettings.ReadInt(asSessionManagerWindowLeft, '', Left);

View File

@ -6,13 +6,30 @@ interface
uses uses
Classes, SysUtils, Forms, Types, StdCtrls, Clipbrd, apphelpers, Classes, SysUtils, Forms, Types, StdCtrls, Clipbrd, apphelpers,
Graphics, Dialogs, ImgList, ComCtrls, Graphics, Dialogs, ImgList, ComCtrls, Generics.Collections, Generics.Defaults,
ExtCtrls, laz.VirtualTrees, RegExpr, Controls, EditBtn, Menus, ExtCtrls, laz.VirtualTrees, RegExpr, Controls, EditBtn, Menus,
GraphUtil; GraphUtil, Math;
type type
// Form with a sizegrip in the lower right corner, without the need for a statusbar // Form with a sizegrip in the lower right corner, without the need for a statusbar
{ TControlTopComparer }
TControlTopComparer = class(TComparer<TControl>)
function Compare(constref Left, Right: TControl): Integer; override;
end;
TControlRow = class(TObjectList<TControl>)
Height: Integer
end;
{ TControlGrid }
TControlGrid = class(TObjectList<TControlRow>)
public
constructor Create(aParentControl: TControl);
end;
{ TExtForm } { TExtForm }
TExtForm = class(TForm) TExtForm = class(TForm)
@ -26,6 +43,7 @@ type
//procedure DoBeforeMonitorDpiChanged(OldDPI, NewDPI: Integer); override; //procedure DoBeforeMonitorDpiChanged(OldDPI, NewDPI: Integer); override;
//procedure DoAfterMonitorDpiChanged(OldDPI, NewDPI: Integer); override; //procedure DoAfterMonitorDpiChanged(OldDPI, NewDPI: Integer); override;
procedure FilterNodesByEdit(Edit: TEditButton; Tree: TLazVirtualStringTree); procedure FilterNodesByEdit(Edit: TEditButton; Tree: TLazVirtualStringTree);
procedure ArrangeControls(aParentControl: TControl);
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
class procedure InheritFont(AFont: TFont); class procedure InheritFont(AFont: TFont);
@ -115,6 +133,69 @@ type
implementation implementation
{ TControlComparer }
function TControlTopComparer.Compare(constref Left, Right: TControl): Integer;
begin
// Sort by Top position, so we can be sure if we find a first one in a row, there's no other above it
if Left.Top > Right.Top then
Result := 1
else if Left.Top = Right.Top then
Result := 0
else
Result := -1;
end;
{ TControlGrid }
constructor TControlGrid.Create(aParentControl: TControl);
const
yCoordStep = 10;
var
y, i: Integer;
FoundControl: TControl;
ControlRow: TControlRow;
AllControls: TObjectList<TControl>;
begin
OwnsObjects := True;
y := 0;
AllControls := TObjectList<TControl>.Create(TControlTopComparer.Create, False);
for i:=0 to aParentControl.Owner.ComponentCount-1 do begin
if aParentControl.Owner.Components[i] is TControl then begin
FoundControl := aParentControl.Owner.Components[i] as TControl;
if FoundControl.Parent = aParentControl then begin
AllControls.Add(FoundControl);
end;
end;
end;
AllControls.Sort;
while y < aParentControl.Height + 100 do begin
ControlRow := TControlRow.Create(False);
ControlRow.Height := 0;
for FoundControl in AllControls do begin
if (FoundControl.Top >= y) and (FoundControl.Top < y + yCoordStep) then begin
ControlRow.Add(FoundControl);
if ControlRow.Count = 1 then
y := FoundControl.Top;
ControlRow.Height := Max(ControlRow.Height, FoundControl.Height);
end;
end;
// Add to grid if controls exist
if ControlRow.Count = 0 then begin
ControlRow.Free;
Inc(y, 1);
end
else begin
Add(ControlRow);
Inc(y, yCoordStep);
end;
end;
end;
{ TExtForm } { TExtForm }
@ -425,6 +506,39 @@ begin
//Edit.Button.Visible := IsNotEmpty(Edit.Text); //Edit.Button.Visible := IsNotEmpty(Edit.Text);
end; end;
procedure TExtForm.ArrangeControls(aParentControl: TControl);
const
PaddingPx = 6;
LabelMoveDown = 2;
var
Grid: TControlGrid;
Row: TControlRow;
FoundControl: TControl;
NewTopPos: Integer;
begin
// Reposition edits and combo boxes due to different height on different OS's
Grid := TControlGrid.Create(aParentControl);
NewTopPos := PaddingPx;
for Row in Grid do begin
for FoundControl in Row do begin
if (akBottom in FoundControl.Anchors) and (akTop in FoundControl.Anchors) then
FoundControl.Height := FoundControl.Height + (FoundControl.Top - NewTopPos);
if (FoundControl is TLabel) and (FoundControl.Left < 30) then begin
FoundControl.Top := NewTopPos + LabelMoveDown;
FoundControl.Left := PaddingPx;
end
else begin
FoundControl.Top := NewTopPos;
end;
if (akRight in FoundControl.Anchors) and (FoundControl.Left + FoundControl.Width > aParentControl.Width - 30) then begin
FoundControl.Width := aParentControl.Width - FoundControl.Left - PaddingPx;
end;
end;
Inc(NewTopPos, Row.Height + PaddingPx);
end;
Grid.Free;
end;
function TExtForm.ScaleSize(x: Extended): Integer; function TExtForm.ScaleSize(x: Extended): Integer;
begin begin