mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-09 09:59:15 +02:00
LCL: Testcase for ChildSizing
This commit is contained in:
parent
22881f66db
commit
2a04d89400
826
lcl/testcase/test_childsizing.pas
Normal file
826
lcl/testcase/test_childsizing.pas
Normal file
@ -0,0 +1,826 @@
|
||||
unit Test_ChildSizing;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
{off $DEFINE WITHOUT_AUTOSIZE_LOCK} // Don't call DisableAutoSizing / let Autosize compute every intermediate result / SLOW
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, Math, fpcunit, testutils, testregistry, Controls;
|
||||
|
||||
type
|
||||
TIntegerArray = array of integer;
|
||||
|
||||
{ TTestWinControl }
|
||||
|
||||
TTestWinControl = class(TWinControl)
|
||||
private
|
||||
FTestVisible: boolean;
|
||||
FPrefWidth, FPrefHeight: Integer;
|
||||
protected
|
||||
procedure CreateHandle; override;
|
||||
procedure DestroyHandle; override;
|
||||
function IsVisible: Boolean; override;
|
||||
function IsControlVisible: Boolean; override;
|
||||
procedure GetPreferredSize(var PreferredWidth, PreferredHeight: Integer; Raw: Boolean = false;
|
||||
WithThemeSpace: Boolean = true); override;
|
||||
public
|
||||
constructor Create(TheOwner: TComponent); override;
|
||||
procedure SetTestPrefSize(APrefWidth, APrefHeight: Integer);
|
||||
property TestVisible: boolean read FTestVisible write FTestVisible;
|
||||
end;
|
||||
|
||||
{ TTestChild }
|
||||
|
||||
TTestChild = class(TTestWinControl)
|
||||
public
|
||||
constructor Create(TheOwner: TWinControl);
|
||||
constructor Create(TheOwner: TWinControl; APrefWidth, APrefHeight: Integer);
|
||||
end;
|
||||
|
||||
{ TTestContainer }
|
||||
|
||||
TTestContainer = class(TTestWinControl)
|
||||
protected
|
||||
function AutoSizeDelayedHandle: Boolean; override;
|
||||
public
|
||||
end;
|
||||
|
||||
TTestChildArray = array of TTestChild;
|
||||
|
||||
{ TTestChildSizing }
|
||||
|
||||
TTestChildSizing = class(TTestCase)
|
||||
private
|
||||
FContainer: TTestContainer;
|
||||
protected
|
||||
class procedure AssertApprox(Expected, Actual: integer);
|
||||
class procedure AssertApprox(AName: String; Expected, Actual: integer);
|
||||
class procedure AssertNoDecrementInList(ANew,AOld: TIntegerArray);
|
||||
class procedure AssertMaxOneDecrementInList(ANew,AOld: TIntegerArray);
|
||||
procedure Init1(
|
||||
out P: TTestContainer; AContainerWidth: integer;
|
||||
AStyle: TChildControlResizeStyle; APerLine: Integer;
|
||||
out C: TTestChildArray; AWidths: array of integer);
|
||||
procedure AddPaddingAround(var C: TTestChildArray; APadding: integer; ALowIdx: Integer = -1; AHighIdx: integer = -1);
|
||||
function GetLefts(C: TTestChildArray; ALowIdx, AHighIdx: integer): TIntegerArray;
|
||||
function GetWidths(C: TTestChildArray; ALowIdx, AHighIdx: integer): TIntegerArray;
|
||||
function SumWidths(C: TTestChildArray; ALowIdx, AHighIdx: integer): integer;
|
||||
function GetSpaces(C: TTestChildArray; AStartX, ATotalWidth, ALowIdx, AHighIdx: integer): TIntegerArray;
|
||||
function SumSpaces(s: TIntegerArray): integer;
|
||||
public
|
||||
procedure TearDown; override;
|
||||
published
|
||||
procedure TestScaleChilds;
|
||||
procedure TestScaleChildsConstrained;
|
||||
procedure TestSameSize;
|
||||
procedure TestSameSizeConstrained;
|
||||
procedure TestHomogenousChildResize;
|
||||
procedure TestHomogenousChildResizeConstrained;
|
||||
procedure TestHomogenousSpaceResize;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TTestWinControl }
|
||||
|
||||
procedure TTestWinControl.CreateHandle;
|
||||
begin
|
||||
Handle := 1;
|
||||
end;
|
||||
|
||||
procedure TTestWinControl.DestroyHandle;
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
function TTestWinControl.IsVisible: Boolean;
|
||||
begin
|
||||
Result := FTestVisible;
|
||||
end;
|
||||
|
||||
function TTestWinControl.IsControlVisible: Boolean;
|
||||
begin
|
||||
Result := FTestVisible;
|
||||
end;
|
||||
|
||||
procedure TTestWinControl.GetPreferredSize(var PreferredWidth, PreferredHeight: Integer;
|
||||
Raw: Boolean; WithThemeSpace: Boolean);
|
||||
begin
|
||||
PreferredWidth := FPrefWidth;
|
||||
PreferredHeight := FPrefHeight;
|
||||
end;
|
||||
|
||||
constructor TTestWinControl.Create(TheOwner: TComponent);
|
||||
begin
|
||||
inherited Create(TheOwner);
|
||||
FTestVisible := True;
|
||||
end;
|
||||
|
||||
procedure TTestWinControl.SetTestPrefSize(APrefWidth, APrefHeight: Integer);
|
||||
begin
|
||||
FPrefWidth := APrefWidth;
|
||||
FPrefHeight := APrefHeight;
|
||||
end;
|
||||
|
||||
{ TTestChild }
|
||||
|
||||
constructor TTestChild.Create(TheOwner: TWinControl);
|
||||
begin
|
||||
inherited Create(TheOwner);
|
||||
Parent := TheOwner;
|
||||
end;
|
||||
|
||||
constructor TTestChild.Create(TheOwner: TWinControl; APrefWidth, APrefHeight: Integer);
|
||||
begin
|
||||
Create(TheOwner);
|
||||
SetTestPrefSize(APrefWidth, APrefHeight);
|
||||
end;
|
||||
|
||||
{ TTestContainer }
|
||||
|
||||
function TTestContainer.AutoSizeDelayedHandle: Boolean;
|
||||
begin
|
||||
Result := False;
|
||||
end;
|
||||
|
||||
{ TTestChildSizing }
|
||||
|
||||
class procedure TTestChildSizing.AssertApprox(Expected, Actual: integer);
|
||||
begin
|
||||
if Actual = Expected + 1 then dec(Actual);
|
||||
AssertEquals(Expected, Actual);
|
||||
end;
|
||||
|
||||
class procedure TTestChildSizing.AssertApprox(AName: String; Expected, Actual: integer);
|
||||
begin
|
||||
if Actual = Expected + 1 then dec(Actual);
|
||||
AssertEquals(AName, Expected, Actual);
|
||||
end;
|
||||
|
||||
class procedure TTestChildSizing.AssertNoDecrementInList(ANew, AOld: TIntegerArray);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
AssertEquals('NO DECR', Length(ANew), Length(AOld));
|
||||
for i := 0 to Length(ANew) - 1 do
|
||||
AssertTrue('NO DECR', ANew[i] >= AOld[i]);
|
||||
end;
|
||||
|
||||
class procedure TTestChildSizing.AssertMaxOneDecrementInList(ANew, AOld: TIntegerArray);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
AssertEquals('MAX ONE DECR', Length(ANew), Length(AOld));
|
||||
for i := 0 to Length(ANew) - 1 do
|
||||
AssertTrue('MAX ONE DECR', ANew[i] >= AOld[i]-1);
|
||||
end;
|
||||
|
||||
procedure TTestChildSizing.Init1(out P: TTestContainer; AContainerWidth: integer;
|
||||
AStyle: TChildControlResizeStyle; APerLine: Integer; out C: TTestChildArray;
|
||||
AWidths: array of integer);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
P := TTestContainer.Create(nil);
|
||||
P.SetBounds(0,0, AContainerWidth, 150);
|
||||
p.ChildSizing.ControlsPerLine := APerLine;
|
||||
p.ChildSizing.EnlargeHorizontal := AStyle;
|
||||
p.ChildSizing.ShrinkHorizontal := AStyle;
|
||||
p.ChildSizing.Layout := cclLeftToRightThenTopToBottom;
|
||||
|
||||
{$IFnDEF WITHOUT_AUTOSIZE_LOCK} p.DisableAutoSizing; {$ENDIF}
|
||||
SetLength(C, Length(AWidths));
|
||||
for i := 0 to Length(AWidths) - 1 do
|
||||
C[i] := TTestChild.Create(P, AWidths[i], 10);
|
||||
{$IFnDEF WITHOUT_AUTOSIZE_LOCK} P.EnableAutoSizing; {$ENDIF}
|
||||
end;
|
||||
|
||||
procedure TTestChildSizing.AddPaddingAround(var C: TTestChildArray; APadding: integer;
|
||||
ALowIdx: Integer; AHighIdx: integer);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
if ALowIdx = -1 then ALowIdx := low(C);
|
||||
if AHighIdx = -1 then AHighIdx := High(C);
|
||||
{$IFnDEF WITHOUT_AUTOSIZE_LOCK} FContainer.DisableAutoSizing; {$ENDIF}
|
||||
for i := ALowIdx to AHighIdx do
|
||||
C[i].BorderSpacing.Around := APadding;
|
||||
{$IFnDEF WITHOUT_AUTOSIZE_LOCK} FContainer.EnableAutoSizing; {$ENDIF}
|
||||
end;
|
||||
|
||||
function TTestChildSizing.GetLefts(C: TTestChildArray; ALowIdx, AHighIdx: integer): TIntegerArray;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
SetLength(Result, AHighIdx - ALowIdx + 1);
|
||||
for i := ALowIdx to AHighIdx do
|
||||
Result[i-ALowIdx] := C[i].Left;
|
||||
end;
|
||||
|
||||
function TTestChildSizing.GetWidths(C: TTestChildArray; ALowIdx, AHighIdx: integer): TIntegerArray;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
SetLength(Result, AHighIdx - ALowIdx + 1);
|
||||
for i := ALowIdx to AHighIdx do
|
||||
Result[i-ALowIdx] := C[i].Width;
|
||||
end;
|
||||
|
||||
function TTestChildSizing.SumWidths(C: TTestChildArray; ALowIdx, AHighIdx: integer): integer;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result := 0;
|
||||
for i := ALowIdx to AHighIdx do
|
||||
Result := Result + C[i].Width;
|
||||
end;
|
||||
|
||||
function TTestChildSizing.GetSpaces(C: TTestChildArray; AStartX, ATotalWidth, ALowIdx,
|
||||
AHighIdx: integer): TIntegerArray;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
SetLength(Result, AHighIdx - ALowIdx + 2);
|
||||
Result[0] := C[ALowIdx].Left - AStartX;
|
||||
for i := ALowIdx to AHighIdx - 1 do
|
||||
Result[1+i-ALowIdx] := C[i+1].Left - (C[i].Left + C[i].Width);
|
||||
Result[1+AHighIdx-ALowIdx] := ATotalWidth - (C[AHighIdx].Left + C[AHighIdx].Width);
|
||||
end;
|
||||
|
||||
function TTestChildSizing.SumSpaces(s: TIntegerArray): integer;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result := 0;
|
||||
for i := low(s) to High(s) do
|
||||
Result := Result + s[i];
|
||||
end;
|
||||
|
||||
procedure TTestChildSizing.TearDown;
|
||||
begin
|
||||
inherited TearDown;
|
||||
FreeAndNil(FContainer);
|
||||
end;
|
||||
|
||||
procedure TTestChildSizing.TestScaleChilds;
|
||||
var
|
||||
C: TTestChildArray;
|
||||
i, MinVal, ALeftSpace, AMidSpace, ACtrlSpace, TotalSpace, j, k: Integer;
|
||||
WList, OldWList, LList, OldLList: TIntegerArray;
|
||||
begin
|
||||
for ALeftSpace := 0 to 3 do
|
||||
for AMidSpace := 0 to 3 do
|
||||
for ACtrlSpace := 0 to 2 do
|
||||
begin
|
||||
TotalSpace := 2*Max(ALeftSpace, ACtrlSpace) + 2*Max(AMidSpace, ACtrlSpace);
|
||||
Init1(FContainer, 300 + TotalSpace,crsScaleChilds, 3, C,
|
||||
[20, 70, 30,
|
||||
20, 35 {-}]);
|
||||
{$IFnDEF WITHOUT_AUTOSIZE_LOCK} FContainer.DisableAutoSizing; {$ENDIF}
|
||||
FContainer.ChildSizing.LeftRightSpacing := ALeftSpace;
|
||||
FContainer.ChildSizing.HorizontalSpacing := AMidSpace;
|
||||
AddPaddingAround(C, ACtrlSpace);
|
||||
{$IFnDEF WITHOUT_AUTOSIZE_LOCK} FContainer.EnableAutoSizing; {$ENDIF}
|
||||
|
||||
AssertEquals(50, C[0].Width);
|
||||
AssertEquals(50, C[3].Width);
|
||||
AssertEquals(175, C[1].Width);
|
||||
AssertEquals(175, C[4].Width);
|
||||
AssertEquals(75, C[2].Width);
|
||||
|
||||
for j := 0 to 1000 do begin
|
||||
FContainer.Width := j;
|
||||
i := Max(0, j - TotalSpace);
|
||||
MinVal := 1;
|
||||
if i <= 2 then MinVal := 0;
|
||||
|
||||
WList := GetWidths(C, 0,2);
|
||||
if j > 0 then
|
||||
AssertMaxOneDecrementInList(WList, OldWList);
|
||||
OldWList := WList;
|
||||
LList := GetLefts(C, 0,2);
|
||||
if j > 0 then
|
||||
AssertNoDecrementInList(LList, OldLList);
|
||||
OldLList := LList;
|
||||
|
||||
k := 0;
|
||||
if i < 4 then k := -1; // column 2 may be restricted by others forced to 1
|
||||
AssertEquals('Total Width', i, SumWidths(C, 0, 2));
|
||||
AssertApprox(Max(MinVal, 20 * i div 120), C[0].Width);
|
||||
AssertApprox(Max(MinVal, 20 * i div 120), C[3].Width);
|
||||
AssertApprox(Max(MinVal, 70 * i div 120 + k), C[1].Width);
|
||||
AssertApprox(Max(MinVal, 70 * i div 120 + k), C[4].Width);
|
||||
AssertApprox(Max(MinVal, 30 * i div 120), C[2].Width);
|
||||
AssertEquals(Max(ALeftSpace, ACtrlSpace) + 0, C[0].Left);
|
||||
AssertEquals(Max(ALeftSpace, ACtrlSpace) + 0, C[3].Left);
|
||||
AssertEquals(Max(ALeftSpace, ACtrlSpace) + Max(AMidSpace, ACtrlSpace) + C[0].Width, C[1].Left);
|
||||
AssertEquals(Max(ALeftSpace, ACtrlSpace) + Max(AMidSpace, ACtrlSpace) + C[0].Width, C[4].Left);
|
||||
AssertEquals(Max(ALeftSpace, ACtrlSpace) + Max(AMidSpace, ACtrlSpace) * 2 + C[0].Width+C[1].Width, C[2].Left);
|
||||
end;
|
||||
FreeAndNil(FContainer);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TTestChildSizing.TestScaleChildsConstrained;
|
||||
var
|
||||
C: TTestChildArray;
|
||||
i, MinVal, ALeftSpace, AMidSpace, TotalSpace, j, k: Integer;
|
||||
WList, OldWList, LList, OldLList: TIntegerArray;
|
||||
begin
|
||||
for ALeftSpace := 0 to 3 do
|
||||
for AMidSpace := 0 to 3 do
|
||||
begin
|
||||
TotalSpace := 2*ALeftSpace + 2*AMidSpace;
|
||||
Init1(FContainer, 170 + TotalSpace,crsScaleChilds, 3, C,
|
||||
[20, 40, 30,
|
||||
20, 35 {-}]);
|
||||
{$IFnDEF WITHOUT_AUTOSIZE_LOCK} FContainer.DisableAutoSizing; {$ENDIF}
|
||||
FContainer.ChildSizing.LeftRightSpacing := ALeftSpace;
|
||||
FContainer.ChildSizing.HorizontalSpacing := AMidSpace;
|
||||
c[1].Constraints.MinWidth := 35;
|
||||
c[1].Constraints.MaxWidth := 45;
|
||||
c[4].Constraints.MinWidth := 35;
|
||||
c[4].Constraints.MaxWidth := 45;
|
||||
{$IFnDEF WITHOUT_AUTOSIZE_LOCK} FContainer.EnableAutoSizing; {$ENDIF}
|
||||
|
||||
AssertEquals(50, C[0].Width);
|
||||
AssertEquals(50, C[3].Width);
|
||||
AssertEquals(45, C[1].Width);
|
||||
AssertEquals(45, C[4].Width);
|
||||
AssertEquals(75, C[2].Width);
|
||||
|
||||
for j := 0 to 1000 do begin
|
||||
FContainer.Width := j;
|
||||
i := Max(0, j - TotalSpace);
|
||||
MinVal := 1;
|
||||
if i < 2+35 then MinVal := 0;
|
||||
|
||||
WList := GetWidths(C, 0,2);
|
||||
if j > 0 then
|
||||
AssertMaxOneDecrementInList(WList, OldWList);
|
||||
OldWList := WList;
|
||||
LList := GetLefts(C, 0,2);
|
||||
if j > 0 then
|
||||
AssertNoDecrementInList(LList, OldLList);
|
||||
OldLList := LList;
|
||||
|
||||
AssertEquals('Total Width', Max(35, i), SumWidths(C, 0, 2));
|
||||
|
||||
if i <= 35 then begin
|
||||
AssertEquals(MinVal, C[0].Width);
|
||||
AssertEquals(MinVal, C[3].Width);
|
||||
AssertEquals(35, C[1].Width);
|
||||
AssertEquals(35, C[4].Width);
|
||||
AssertEquals(MinVal, C[2].Width);
|
||||
end
|
||||
else
|
||||
if i <= 80 then begin
|
||||
AssertApprox(Max(MinVal, 20 * (i-35) div 50), C[0].Width);
|
||||
AssertApprox(Max(MinVal, 20 * (i-35) div 50), C[3].Width);
|
||||
AssertEquals(35, C[1].Width);
|
||||
AssertEquals(35, C[4].Width);
|
||||
AssertApprox(Max(MinVal, 30 * (i-35) div 50), C[2].Width);
|
||||
end
|
||||
else
|
||||
if i <= 101 then begin
|
||||
AssertApprox(20 * i div 90, C[0].Width);
|
||||
AssertApprox(20 * i div 90, C[3].Width);
|
||||
AssertApprox(40 * i div 90, C[1].Width);
|
||||
AssertApprox(40 * i div 90, C[4].Width);
|
||||
AssertApprox(30 * i div 90, C[2].Width);
|
||||
end
|
||||
else
|
||||
begin
|
||||
AssertApprox(20 * (i-45) div 50, C[0].Width);
|
||||
AssertApprox(20 * (i-45) div 50, C[3].Width);
|
||||
AssertEquals(45, C[1].Width);
|
||||
AssertEquals(45, C[4].Width);
|
||||
AssertApprox(30 * (i-45) div 50, C[2].Width);
|
||||
end;
|
||||
|
||||
AssertEquals(ALeftSpace + 0, C[0].Left);
|
||||
AssertEquals(ALeftSpace + 0, C[3].Left);
|
||||
AssertEquals(ALeftSpace + AMidSpace + C[0].Width, C[1].Left);
|
||||
AssertEquals(ALeftSpace + AMidSpace + C[0].Width, C[4].Left);
|
||||
AssertEquals(ALeftSpace + AMidSpace * 2 + C[0].Width+C[1].Width, C[2].Left);
|
||||
end;
|
||||
FreeAndNil(FContainer);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TTestChildSizing.TestSameSize;
|
||||
var
|
||||
C: TTestChildArray;
|
||||
i, MinVal, ALeftSpace, AMidSpace, ACtrlSpace, TotalSpace, j: Integer;
|
||||
WList, OldWList, LList, OldLList: TIntegerArray;
|
||||
begin
|
||||
for ALeftSpace := 0 to 3 do
|
||||
for AMidSpace := 0 to 3 do
|
||||
for ACtrlSpace := 0 to 2 do
|
||||
begin
|
||||
TotalSpace := 2*Max(ALeftSpace, ACtrlSpace) + 2*Max(AMidSpace, ACtrlSpace);
|
||||
Init1(FContainer, 150 + TotalSpace,crsSameSize, 3, C,
|
||||
[20, 40, 30,
|
||||
20, 35 {-}]);
|
||||
{$IFnDEF WITHOUT_AUTOSIZE_LOCK} FContainer.DisableAutoSizing; {$ENDIF}
|
||||
FContainer.ChildSizing.LeftRightSpacing := ALeftSpace;
|
||||
FContainer.ChildSizing.HorizontalSpacing := AMidSpace;
|
||||
AddPaddingAround(C, ACtrlSpace);
|
||||
{$IFnDEF WITHOUT_AUTOSIZE_LOCK} FContainer.EnableAutoSizing; {$ENDIF}
|
||||
|
||||
AssertEquals(50, C[0].Width);
|
||||
AssertEquals(50, C[3].Width);
|
||||
AssertEquals(50, C[1].Width);
|
||||
AssertEquals(50, C[4].Width);
|
||||
AssertEquals(50, C[2].Width);
|
||||
|
||||
for j := 0 to 1000 do begin
|
||||
FContainer.Width := j;
|
||||
i := Max(0, j - TotalSpace);
|
||||
MinVal := 1;
|
||||
if i <= 2 then MinVal := 0;
|
||||
|
||||
WList := GetWidths(C, 0,2);
|
||||
if j > 0 then
|
||||
AssertMaxOneDecrementInList(WList, OldWList);
|
||||
OldWList := WList;
|
||||
LList := GetLefts(C, 0,2);
|
||||
if j > 0 then
|
||||
AssertNoDecrementInList(LList, OldLList);
|
||||
OldLList := LList;
|
||||
|
||||
AssertEquals('Total Width', i, SumWidths(C, 0, 2));
|
||||
AssertApprox(Max(MinVal, i div 3), C[0].Width);
|
||||
AssertApprox(Max(MinVal, i div 3), C[3].Width);
|
||||
AssertApprox(Max(MinVal, i div 3), C[1].Width);
|
||||
AssertApprox(Max(MinVal, i div 3), C[4].Width);
|
||||
AssertApprox(Max(MinVal, i div 3), C[2].Width);
|
||||
AssertEquals(Max(ALeftSpace, ACtrlSpace) + 0, C[0].Left);
|
||||
AssertEquals(Max(ALeftSpace, ACtrlSpace) + 0, C[3].Left);
|
||||
AssertEquals(Max(ALeftSpace, ACtrlSpace) + Max(AMidSpace, ACtrlSpace) + C[0].Width, C[1].Left);
|
||||
AssertEquals(Max(ALeftSpace, ACtrlSpace) + Max(AMidSpace, ACtrlSpace) + C[0].Width, C[4].Left);
|
||||
AssertEquals(Max(ALeftSpace, ACtrlSpace) + Max(AMidSpace, ACtrlSpace) *2 + C[0].Width+C[1].Width, C[2].Left);
|
||||
end;
|
||||
FreeAndNil(FContainer);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TTestChildSizing.TestSameSizeConstrained;
|
||||
var
|
||||
C: TTestChildArray;
|
||||
i, MinVal, ALeftSpace, AMidSpace, TotalSpace, j: Integer;
|
||||
WList, OldWList, LList, OldLList: TIntegerArray;
|
||||
begin
|
||||
for ALeftSpace := 0 to 3 do
|
||||
for AMidSpace := 0 to 3 do
|
||||
begin
|
||||
TotalSpace := 2*ALeftSpace + 2*AMidSpace;
|
||||
Init1(FContainer, 145 + TotalSpace,crsSameSize, 3, C,
|
||||
[20, 40, 30,
|
||||
20, 35 {-}]);
|
||||
{$IFnDEF WITHOUT_AUTOSIZE_LOCK} FContainer.DisableAutoSizing; {$ENDIF}
|
||||
FContainer.ChildSizing.LeftRightSpacing := ALeftSpace;
|
||||
FContainer.ChildSizing.HorizontalSpacing := AMidSpace;
|
||||
c[1].Constraints.MinWidth := 35;
|
||||
c[1].Constraints.MaxWidth := 45;
|
||||
c[4].Constraints.MinWidth := 35;
|
||||
c[4].Constraints.MaxWidth := 45;
|
||||
{$IFnDEF WITHOUT_AUTOSIZE_LOCK} FContainer.EnableAutoSizing; {$ENDIF}
|
||||
|
||||
AssertEquals(50, C[0].Width);
|
||||
AssertEquals(50, C[3].Width);
|
||||
AssertEquals(45, C[1].Width);
|
||||
AssertEquals(45, C[4].Width);
|
||||
AssertEquals(50, C[2].Width);
|
||||
|
||||
for j := 0 to 1000 do begin
|
||||
FContainer.Width := j;
|
||||
i := Max(0, j - TotalSpace);
|
||||
MinVal := 1;
|
||||
if i < 2+35 then MinVal := 0;
|
||||
|
||||
WList := GetWidths(C, 0,2);
|
||||
if j > 0 then
|
||||
AssertMaxOneDecrementInList(WList, OldWList);
|
||||
OldWList := WList;
|
||||
LList := GetLefts(C, 0,2);
|
||||
if j > 0 then
|
||||
AssertNoDecrementInList(LList, OldLList);
|
||||
OldLList := LList;
|
||||
|
||||
AssertEquals('Total Width', Max(35, i), SumWidths(C, 0, 2));
|
||||
|
||||
if i <= 35 then begin
|
||||
AssertEquals(MinVal, C[0].Width);
|
||||
AssertEquals(MinVal, C[3].Width);
|
||||
AssertEquals(35, C[1].Width);
|
||||
AssertEquals(35, C[4].Width);
|
||||
AssertEquals(MinVal, C[2].Width);
|
||||
end
|
||||
else
|
||||
if i <= 105 then begin
|
||||
AssertApprox(Max(MinVal, (i-35) div 2), C[0].Width);
|
||||
AssertApprox(Max(MinVal, (i-35) div 2), C[3].Width);
|
||||
AssertEquals(35, C[1].Width);
|
||||
AssertEquals(35, C[4].Width);
|
||||
AssertApprox(Max(MinVal, (i-35) div 2), C[2].Width);
|
||||
end
|
||||
else
|
||||
if i <= 135 then begin
|
||||
AssertApprox(Max(MinVal, i div 3), C[0].Width);
|
||||
AssertApprox(Max(MinVal, i div 3), C[3].Width);
|
||||
AssertApprox(Max(MinVal, i div 3), C[1].Width);
|
||||
AssertApprox(Max(MinVal, i div 3), C[4].Width);
|
||||
AssertApprox(Max(MinVal, i div 3), C[2].Width);
|
||||
end
|
||||
else
|
||||
begin
|
||||
AssertApprox(Max(MinVal, (i-45) div 2), C[0].Width);
|
||||
AssertApprox(Max(MinVal, (i-45) div 2), C[3].Width);
|
||||
AssertEquals(45, C[1].Width);
|
||||
AssertEquals(45, C[4].Width);
|
||||
AssertApprox(Max(MinVal, (i-45) div 2), C[2].Width);
|
||||
end;
|
||||
|
||||
AssertEquals(ALeftSpace + 0, C[0].Left);
|
||||
AssertEquals(ALeftSpace + 0, C[3].Left);
|
||||
AssertEquals(ALeftSpace + AMidSpace + C[0].Width, C[1].Left);
|
||||
AssertEquals(ALeftSpace + AMidSpace + C[0].Width, C[4].Left);
|
||||
AssertEquals(ALeftSpace + AMidSpace *2 + C[0].Width+C[1].Width, C[2].Left);
|
||||
end;
|
||||
FreeAndNil(FContainer);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TTestChildSizing.TestHomogenousChildResize;
|
||||
var
|
||||
C: TTestChildArray;
|
||||
i, ALeftSpace, AMidSpace, ACtrlSpace, TotalSpace, j: Integer;
|
||||
WList, OldWList, LList, OldLList: TIntegerArray;
|
||||
begin
|
||||
for ALeftSpace := 0 to 3 do
|
||||
for AMidSpace := 0 to 3 do
|
||||
for ACtrlSpace := 0 to 2 do
|
||||
begin
|
||||
TotalSpace := 2*Max(ALeftSpace, ACtrlSpace) + 2*Max(AMidSpace, ACtrlSpace);
|
||||
Init1(FContainer, 120 + TotalSpace, crsHomogenousChildResize, 3, C,
|
||||
[20, 40, 30,
|
||||
20, 35 {-}]);
|
||||
{$IFnDEF WITHOUT_AUTOSIZE_LOCK} FContainer.DisableAutoSizing; {$ENDIF}
|
||||
FContainer.ChildSizing.LeftRightSpacing := ALeftSpace;
|
||||
FContainer.ChildSizing.HorizontalSpacing := AMidSpace;
|
||||
AddPaddingAround(C, ACtrlSpace);
|
||||
{$IFnDEF WITHOUT_AUTOSIZE_LOCK} FContainer.EnableAutoSizing; {$ENDIF}
|
||||
|
||||
AssertEquals(30, C[0].Width);
|
||||
AssertEquals(30, C[3].Width);
|
||||
AssertEquals(50, C[1].Width);
|
||||
AssertEquals(50, C[4].Width);
|
||||
AssertEquals(40, C[2].Width);
|
||||
|
||||
for j := 0 to 1000 do begin
|
||||
FContainer.Width := j;
|
||||
i := Max(0, j - TotalSpace);
|
||||
|
||||
WList := GetWidths(C, 0,2);
|
||||
if j > 0 then
|
||||
AssertMaxOneDecrementInList(WList, OldWList);
|
||||
OldWList := WList;
|
||||
LList := GetLefts(C, 0,2);
|
||||
if j > 0 then
|
||||
AssertNoDecrementInList(LList, OldLList);
|
||||
OldLList := LList;
|
||||
|
||||
AssertEquals('Total Width', i, SumWidths(C, 0, 2));
|
||||
if i < 3 then begin // All column are limited
|
||||
AssertApprox(0, C[0].Width);
|
||||
AssertApprox(0, C[3].Width);
|
||||
AssertApprox(0, C[1].Width);
|
||||
AssertApprox(0, C[4].Width);
|
||||
AssertApprox(0, C[2].Width);
|
||||
end
|
||||
else
|
||||
if i <= 11 then begin // First and Last column is limited
|
||||
// 11 = 90 - 79 = 90 - 19 (1st) + 2*30
|
||||
AssertEquals(1, C[0].Width);
|
||||
AssertEquals(1, C[3].Width);
|
||||
// 40 + (i - (90 - (19+29))) div 1
|
||||
AssertEquals(Max(1, i-2), C[1].Width);
|
||||
AssertEquals(Max(1, i-2), C[4].Width);
|
||||
AssertEquals(1, C[2].Width);
|
||||
end
|
||||
else
|
||||
if i <= 30 then begin // First column is limited
|
||||
// 30 = 90 - 60 = 90 - 3*20 to subtract => first column forced to 1
|
||||
AssertEquals(1, C[0].Width);
|
||||
AssertEquals(1, C[3].Width);
|
||||
AssertApprox(Max(1, -1 + 40 + (i-(90-19)) div 2), C[1].Width);
|
||||
AssertApprox(Max(1, -1 + 40 + (i-(90-19)) div 2), C[4].Width);
|
||||
AssertApprox(Max(1, -1 + 30 + (i-(90-19)) div 2), C[2].Width);
|
||||
end
|
||||
else
|
||||
if i <= 90 then begin // shrink
|
||||
AssertApprox(Max(1, -1 + 20 + (i-90) div 3), C[0].Width);
|
||||
AssertApprox(Max(1, -1 + 20 + (i-90) div 3), C[3].Width);
|
||||
AssertApprox(Max(1, -1 + 40 + (i-90) div 3), C[1].Width);
|
||||
AssertApprox(Max(1, -1 + 40 + (i-90) div 3), C[4].Width);
|
||||
AssertApprox(Max(1, -1 + 30 + (i-90) div 3), C[2].Width);
|
||||
end
|
||||
else begin
|
||||
// enlarge
|
||||
AssertApprox(max(1, 20 + (i-90) div 3), C[0].Width);
|
||||
AssertApprox(Max(1, 20 + (i-90) div 3), C[3].Width);
|
||||
AssertApprox(Max(1, 40 + (i-90) div 3), C[1].Width);
|
||||
AssertApprox(Max(1, 40 + (i-90) div 3), C[4].Width);
|
||||
AssertApprox(Max(1, 30 + (i-90) div 3), C[2].Width);
|
||||
end;
|
||||
AssertEquals(Max(ALeftSpace, ACtrlSpace) + 0, C[0].Left);
|
||||
AssertEquals(Max(ALeftSpace, ACtrlSpace) + 0, C[3].Left);
|
||||
AssertEquals(Max(ALeftSpace, ACtrlSpace) + Max(AMidSpace, ACtrlSpace) + C[0].Width, C[1].Left);
|
||||
AssertEquals(Max(ALeftSpace, ACtrlSpace) + Max(AMidSpace, ACtrlSpace) + C[0].Width, C[4].Left);
|
||||
AssertEquals(Max(ALeftSpace, ACtrlSpace) + Max(AMidSpace, ACtrlSpace) * 2 + C[0].Width+C[1].Width, C[2].Left);
|
||||
end;
|
||||
FreeAndNil(FContainer);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TTestChildSizing.TestHomogenousChildResizeConstrained;
|
||||
var
|
||||
C: TTestChildArray;
|
||||
i, MinVal, j: Integer;
|
||||
WList, OldWList, LList, OldLList: TIntegerArray;
|
||||
begin
|
||||
Init1(FContainer, 115, crsHomogenousChildResize, 3, C,
|
||||
[20, 40, 30,
|
||||
20, 35 {-}]);
|
||||
{$IFnDEF WITHOUT_AUTOSIZE_LOCK} FContainer.DisableAutoSizing; {$ENDIF}
|
||||
c[1].Constraints.MinWidth := 35;
|
||||
c[1].Constraints.MaxWidth := 45;
|
||||
c[4].Constraints.MinWidth := 35;
|
||||
c[4].Constraints.MaxWidth := 45;
|
||||
{$IFnDEF WITHOUT_AUTOSIZE_LOCK} FContainer.EnableAutoSizing; {$ENDIF}
|
||||
|
||||
// // 90 + 25 (5 Constrained / +20 for the 2 other column)
|
||||
AssertEquals(30, C[0].Width);
|
||||
AssertEquals(30, C[3].Width);
|
||||
AssertEquals(45, C[1].Width);
|
||||
AssertEquals(45, C[4].Width);
|
||||
AssertEquals(40, C[2].Width);
|
||||
|
||||
FContainer.Width := 65; // 90 - 25 (5 Constrained / -20 for the 2 other column)
|
||||
AssertEquals(10, C[0].Width);
|
||||
AssertEquals(10, C[3].Width);
|
||||
AssertEquals(35, C[1].Width);
|
||||
AssertEquals(35, C[4].Width);
|
||||
AssertEquals(20, C[2].Width);
|
||||
|
||||
FContainer.Width := 45; // 90 - 35 (5 Constrained / -30 for the 2 other column)
|
||||
AssertEquals( 1, C[0].Width);
|
||||
AssertEquals( 1, C[3].Width);
|
||||
AssertEquals(35, C[1].Width);
|
||||
AssertEquals(35, C[4].Width);
|
||||
AssertEquals( 9, C[2].Width);
|
||||
|
||||
FContainer.Width := 40; // 90 - 50 (5 Constrained / -45 for the 2 other column)
|
||||
AssertEquals( 1, C[0].Width);
|
||||
AssertEquals( 1, C[3].Width);
|
||||
AssertEquals(35, C[1].Width);
|
||||
AssertEquals(35, C[4].Width);
|
||||
AssertEquals( 4, C[2].Width);
|
||||
|
||||
FContainer.Width := 30;
|
||||
AssertEquals( 0, C[0].Width);
|
||||
AssertEquals( 0, C[3].Width);
|
||||
AssertEquals(35, C[1].Width);
|
||||
AssertEquals(35, C[4].Width);
|
||||
AssertEquals( 0, C[2].Width);
|
||||
|
||||
|
||||
|
||||
for j := 0 to 1000 do begin
|
||||
FContainer.Width := j;
|
||||
i := Max(0, j);
|
||||
|
||||
WList := GetWidths(C, 0,2);
|
||||
if j > 0 then
|
||||
AssertMaxOneDecrementInList(WList, OldWList);
|
||||
OldWList := WList;
|
||||
LList := GetLefts(C, 0,2);
|
||||
if j > 0 then
|
||||
AssertNoDecrementInList(LList, OldLList);
|
||||
OldLList := LList;
|
||||
|
||||
AssertEquals('Total Width', Max(35, i), SumWidths(C, 0, 2));
|
||||
|
||||
AssertEquals(0, C[0].Left);
|
||||
AssertEquals(0, C[3].Left);
|
||||
AssertEquals(C[0].Width, C[1].Left);
|
||||
AssertEquals(C[0].Width, C[4].Left);
|
||||
AssertEquals(C[0].Width+C[1].Width, C[2].Left);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
procedure TTestChildSizing.TestHomogenousSpaceResize;
|
||||
var
|
||||
C: TTestChildArray;
|
||||
i, d, j: Integer;
|
||||
gaps, OldGaps, LList, OldLList: TIntegerArray;
|
||||
begin
|
||||
Init1(FContainer, 120, crsHomogenousSpaceResize, 3, C,
|
||||
[20, 40, 30,
|
||||
20, 35 {-}]);
|
||||
|
||||
for i := 0 to 1000 do begin
|
||||
FContainer.Width := i;
|
||||
AssertEquals('Total Width', 90, SumWidths(C, 0, 2));
|
||||
AssertEquals(20, C[0].Width);
|
||||
AssertEquals(20, C[3].Width);
|
||||
AssertEquals(40, C[1].Width);
|
||||
//AssertEquals(35, C[4].Width); // Even though it's "space resize", the cell size gets applied to all children
|
||||
AssertEquals(30, C[2].Width);
|
||||
|
||||
gaps := GetSpaces(C, 0, Max(90,i), 0,2);
|
||||
AssertEquals('Spaces', Max(0, i-90), SumSpaces(gaps));
|
||||
d := Max(0, i-90) div 4;
|
||||
for j := 0 to Length(gaps) - 1 do
|
||||
AssertApprox(d, gaps[j]);
|
||||
end;
|
||||
FreeAndNil(FContainer);
|
||||
|
||||
/////////////////
|
||||
// With Spacing
|
||||
|
||||
Init1(FContainer, 120, crsHomogenousSpaceResize, 3, C,
|
||||
[20, 40, 30,
|
||||
20, 35 {-}]);
|
||||
{$IFnDEF WITHOUT_AUTOSIZE_LOCK} FContainer.DisableAutoSizing; {$ENDIF}
|
||||
FContainer.ChildSizing.LeftRightSpacing := 9;
|
||||
FContainer.ChildSizing.HorizontalSpacing := 4;
|
||||
C[2].BorderSpacing.Left := 11;
|
||||
{$IFnDEF WITHOUT_AUTOSIZE_LOCK} FContainer.EnableAutoSizing; {$ENDIF}
|
||||
// Spacing 9 C0 4 C1 11 C2 9
|
||||
|
||||
|
||||
for i := 0 to 1000 do begin
|
||||
FContainer.Width := i;
|
||||
AssertEquals('Total Width', 90, SumWidths(C, 0, 2));
|
||||
AssertEquals(20, C[0].Width);
|
||||
AssertEquals(20, C[3].Width);
|
||||
AssertEquals(40, C[1].Width);
|
||||
//AssertEquals(35, C[4].Width); // Even though it's "space resize", the cell size gets applied to all children
|
||||
AssertEquals(30, C[2].Width);
|
||||
|
||||
gaps := GetSpaces(C, 0, Max(90,i), 0,2);
|
||||
if i > 0 then
|
||||
AssertMaxOneDecrementInList(gaps, OldGaps);
|
||||
OldGaps := gaps;
|
||||
LList := GetLefts(C, 0,2);
|
||||
if i > 0 then
|
||||
AssertNoDecrementInList(LList, OldLList);
|
||||
OldLList := LList;
|
||||
AssertEquals('Spaces', Max(0, i-90), SumSpaces(gaps));
|
||||
|
||||
if i <= 90 then begin
|
||||
AssertEquals( 0, gaps[0]);
|
||||
AssertEquals( 0, gaps[1]);
|
||||
AssertEquals( 0, gaps[2]);
|
||||
AssertEquals( 0, gaps[3]);
|
||||
end
|
||||
else
|
||||
if i <= 92 then begin
|
||||
d := i-90;
|
||||
AssertEquals( 0, gaps[0]);
|
||||
AssertEquals( 0, gaps[1]);
|
||||
AssertEquals( 0 + d, gaps[2]); // 91 = 1 .... 92 = 2
|
||||
AssertEquals( 0, gaps[3]);
|
||||
end
|
||||
else
|
||||
if i <= 107 then begin
|
||||
d := Max(0, i-92) div 3; // 93-95=1 .. 105..107=5
|
||||
AssertApprox( 0 + d, gaps[0]);
|
||||
AssertEquals( 0, gaps[1]);
|
||||
AssertApprox( 2 + d, gaps[2]);
|
||||
AssertApprox( 0 + d, gaps[3]);
|
||||
end
|
||||
else
|
||||
if i <= 123 then begin
|
||||
d := Max(0, i-107) div 4;
|
||||
AssertApprox( 5 + d, gaps[0]);
|
||||
AssertApprox( 0 + d, gaps[1]);
|
||||
AssertApprox( 7 + d, gaps[2]);
|
||||
AssertApprox( 5 + d, gaps[3]);
|
||||
end;
|
||||
|
||||
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
initialization
|
||||
|
||||
RegisterTest(TTestChildSizing);
|
||||
end.
|
||||
|
96
lcl/testcase/test_lcl.lpi
Normal file
96
lcl/testcase/test_lcl.lpi
Normal file
@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectOptions>
|
||||
<Version Value="12"/>
|
||||
<PathDelim Value="\"/>
|
||||
<General>
|
||||
<Flags>
|
||||
<MainUnitHasCreateFormStatements Value="False"/>
|
||||
<MainUnitHasTitleStatement Value="False"/>
|
||||
<MainUnitHasScaledStatement Value="False"/>
|
||||
</Flags>
|
||||
<SessionStorage Value="InProjectDir"/>
|
||||
<Title Value="test_lcl"/>
|
||||
<UseAppBundle Value="False"/>
|
||||
<ResourceType Value="res"/>
|
||||
</General>
|
||||
<MacroValues Count="1">
|
||||
<Macro1 Name="LCLWidgetType" Value="nogui"/>
|
||||
</MacroValues>
|
||||
<BuildModes>
|
||||
<Item Name="Default" Default="True"/>
|
||||
<SharedMatrixOptions Count="1">
|
||||
<Item1 ID="887419357598" Modes="Default" Type="IDEMacro" MacroName="LCLWidgetType" Value="nogui"/>
|
||||
</SharedMatrixOptions>
|
||||
</BuildModes>
|
||||
<PublishOptions>
|
||||
<Version Value="2"/>
|
||||
<UseFileFilters Value="True"/>
|
||||
</PublishOptions>
|
||||
<RunParams>
|
||||
<FormatVersion Value="2"/>
|
||||
</RunParams>
|
||||
<RequiredPackages>
|
||||
<Item>
|
||||
<PackageName Value="LCL"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<PackageName Value="FCL"/>
|
||||
</Item>
|
||||
</RequiredPackages>
|
||||
<Units>
|
||||
<Unit>
|
||||
<Filename Value="test_lcl.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="test_childsizing.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="Test_ChildSizing"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<Target>
|
||||
<Filename Value="test_lcl"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<Parsing>
|
||||
<SyntaxOptions>
|
||||
<IncludeAssertionCode Value="True"/>
|
||||
</SyntaxOptions>
|
||||
</Parsing>
|
||||
<CodeGeneration>
|
||||
<Checks>
|
||||
<IOChecks Value="True"/>
|
||||
<RangeChecks Value="True"/>
|
||||
<OverflowChecks Value="True"/>
|
||||
<StackChecks Value="True"/>
|
||||
</Checks>
|
||||
<VerifyObjMethodCallValidity Value="True"/>
|
||||
</CodeGeneration>
|
||||
<Linking>
|
||||
<Debugging>
|
||||
<DebugInfoType Value="dsDwarf3"/>
|
||||
</Debugging>
|
||||
</Linking>
|
||||
</CompilerOptions>
|
||||
<Debugging>
|
||||
<Exceptions>
|
||||
<Item>
|
||||
<Name Value="EAbort"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<Name Value="ECodetoolError"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<Name Value="EFOpenError"/>
|
||||
</Item>
|
||||
</Exceptions>
|
||||
</Debugging>
|
||||
</CONFIG>
|
29
lcl/testcase/test_lcl.lpr
Normal file
29
lcl/testcase/test_lcl.lpr
Normal file
@ -0,0 +1,29 @@
|
||||
program test_lcl;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
uses
|
||||
Interfaces,
|
||||
Classes, consoletestrunner, Test_ChildSizing;
|
||||
|
||||
type
|
||||
|
||||
{ TMyTestRunner }
|
||||
|
||||
TMyTestRunner = class(TTestRunner)
|
||||
protected
|
||||
// override the protected methods of TTestRunner to customize its behavior
|
||||
end;
|
||||
|
||||
var
|
||||
Application: TMyTestRunner;
|
||||
|
||||
begin
|
||||
DefaultRunAllTests:=True;
|
||||
DefaultFormat:=fXML;
|
||||
Application := TMyTestRunner.Create(nil);
|
||||
Application.Initialize;
|
||||
Application.Title := 'FPCUnit Console test runner';
|
||||
Application.Run;
|
||||
Application.Free;
|
||||
end.
|
Loading…
Reference in New Issue
Block a user