mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-29 13:51:24 +02:00
LCL: TScrollingWinControl: use GetPreferredSize to compute ranges, CalculatePreferredSize: fixed computing mix of Layout and non Layout controls, fixed using 0x0 size of TPanel
git-svn-id: trunk@25070 -
This commit is contained in:
parent
c77f948063
commit
ecc75765fe
@ -4841,6 +4841,7 @@ begin
|
||||
PreferredHeight:=Height;
|
||||
end;
|
||||
|
||||
{$IFDEF OldAutoSize}
|
||||
// if this control is aligned adjust PreferredWidth and/or PreferredHeight
|
||||
if WidthIsAnchored then begin
|
||||
// the control will be expanded to maximum width
|
||||
@ -4854,6 +4855,7 @@ begin
|
||||
// aligning code
|
||||
PreferredHeight:=Height;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
// apply constraints
|
||||
PreferredWidth:=Constraints.MinMaxWidth(PreferredWidth);
|
||||
|
@ -219,33 +219,45 @@ procedure TControlScrollBar.AutoCalcRange;
|
||||
|
||||
function IsNonAligned(Control: TControl): boolean;
|
||||
begin
|
||||
Result:=(Control.Align=alNone)
|
||||
Result:=(Control.Align in [alNone,alCustom])
|
||||
and (Control.Anchors=[akLeft,akTop])
|
||||
and (Control.AnchorSide[akLeft].Control=nil)
|
||||
and (Control.AnchorSide[akTop].Control=nil);
|
||||
end;
|
||||
|
||||
procedure GetPreferredClientRect(out PreferredWidth, PreferredHeight: integer);
|
||||
begin
|
||||
PreferredWidth:=0;
|
||||
PreferredHeight:=0;
|
||||
FControl.GetPreferredSize(PreferredWidth,PreferredHeight,true);
|
||||
//DebugLn(['GetPreferredClientRect ',DbgSName(FControl),' Pref=',PreferredWidth,'x',PreferredHeight]);
|
||||
dec(PreferredWidth,FControl.Width-FControl.ClientWidth);
|
||||
dec(PreferredHeight,FControl.Height-FControl.ClientHeight);
|
||||
if PreferredWidth<0 then PreferredWidth:=0;
|
||||
if PreferredHeight<0 then PreferredHeight:=0;
|
||||
end;
|
||||
|
||||
procedure AutoCalcVRange;
|
||||
var
|
||||
I: Integer;
|
||||
TmpRange: Longint;
|
||||
c: TControl;
|
||||
PreferredWidth: Integer;
|
||||
PreferredHeight: Integer;
|
||||
begin
|
||||
TmpRange := 0;
|
||||
for I := 0 to FControl.ControlCount - 1 do
|
||||
begin
|
||||
c:=FControl.Controls[I];
|
||||
if not c.IsControlVisible then continue;
|
||||
if c.Align=alCustom then continue;
|
||||
if akBottom in c.Anchors then continue;
|
||||
if (c.Align<>alNone) and (akBottom in AnchorAlign[c.Align]) then continue;
|
||||
if (FControl.ChildSizing.Layout<>cclNone) and IsNonAligned(c) then continue;
|
||||
if (akTop in c.Anchors) and
|
||||
(c.AnchorSide[akTop].Control <> nil) and
|
||||
(c.AnchorSide[akTop].Control <> c) then
|
||||
continue;
|
||||
TmpRange := Max(TmpRange, c.Top + c.Height);
|
||||
GetPreferredClientRect(PreferredWidth,PreferredHeight);
|
||||
TmpRange := PreferredHeight;
|
||||
if not FControl.AutoSize then begin
|
||||
for I := 0 to FControl.ControlCount - 1 do
|
||||
begin
|
||||
c:=FControl.Controls[I];
|
||||
if not c.IsControlVisible then continue;
|
||||
if not IsNonAligned(c) then continue;
|
||||
//DebugLn(['AutoCalcVRange c=',DbgSName(c)]);
|
||||
TmpRange := Max(TmpRange, c.Top + c.Height);
|
||||
end;
|
||||
end;
|
||||
//DebugLn(['AutoCalcVRange ',DbgSName(FControl),' Bounds=',dbgs(FControl.BoundsRect),' Client=',dbgs(FControl.ClientRect),' TmpRange=',TmpRange,' pref=',PreferredWidth,'x',PreferredHeight]);
|
||||
InternalSetRange(TmpRange);
|
||||
end;
|
||||
|
||||
@ -254,21 +266,19 @@ procedure TControlScrollBar.AutoCalcRange;
|
||||
i: Integer;
|
||||
TmpRange : Longint;
|
||||
c: TControl;
|
||||
PreferredWidth: Integer;
|
||||
PreferredHeight: Integer;
|
||||
begin
|
||||
TmpRange := 0;
|
||||
for i := 0 to FControl.ControlCount - 1 do
|
||||
begin
|
||||
c:=FControl.Controls[I];
|
||||
if not c.IsControlVisible then continue;
|
||||
if c.Align=alCustom then continue;
|
||||
if akRight in c.Anchors then continue;
|
||||
if (c.Align<>alNone) and (akRight in AnchorAlign[c.Align]) then continue;
|
||||
if (FControl.ChildSizing.Layout<>cclNone) and IsNonAligned(c) then continue;
|
||||
if (akLeft in c.Anchors) and
|
||||
(c.AnchorSide[akLeft].Control <> nil) and
|
||||
(c.AnchorSide[akLeft].Control <> c) then
|
||||
continue;
|
||||
TmpRange := Max(TmpRange, c.Left + c.Width);
|
||||
GetPreferredClientRect(PreferredWidth,PreferredHeight);
|
||||
TmpRange := PreferredWidth;
|
||||
if not FControl.AutoSize then begin
|
||||
for i := 0 to FControl.ControlCount - 1 do
|
||||
begin
|
||||
c:=FControl.Controls[I];
|
||||
if not c.IsControlVisible then continue;
|
||||
if not IsNonAligned(c) then continue;
|
||||
TmpRange := Max(TmpRange, c.Left + c.Width);
|
||||
end;
|
||||
end;
|
||||
InternalSetRange(TmpRange);
|
||||
end;
|
||||
|
@ -49,6 +49,13 @@ begin
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
function IsNotAligned(AControl: TControl): boolean;
|
||||
begin
|
||||
Result:=(AControl.Align=alNone)
|
||||
and (AControl.Anchors=[akLeft,akTop])
|
||||
and (AControl.AnchorSide[akLeft].Control=nil)
|
||||
and (AControl.AnchorSide[akTop].Control=nil);
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
Autosizing Helper classes
|
||||
@ -805,9 +812,7 @@ begin
|
||||
Child:=WinControl.Controls[i];
|
||||
ChildData:=Childs[Child];
|
||||
if not ChildData.Visible then continue;
|
||||
if (Child.Align=alNone)
|
||||
and (Side in Child.Anchors) and (Child.AnchorSide[Side].Control=nil)
|
||||
then begin
|
||||
if IsNotAligned(Child) then begin
|
||||
// this is a non aligned control
|
||||
//DebugLn(['TAutoSizeCtrlData.DoMoveNonAlignedChilds Child=',DbgSName(Child),' Side=',dbgs(Side)]);
|
||||
if FindMinimum then begin
|
||||
@ -853,6 +858,7 @@ var
|
||||
MoveDiff: Integer;
|
||||
AlignList: TFPList;
|
||||
r: TRect;
|
||||
i: Integer;
|
||||
begin
|
||||
if ChildCount=0 then exit;
|
||||
if WinControl.ChildSizing.Layout=cclNone then begin
|
||||
@ -875,7 +881,11 @@ begin
|
||||
Box:=nil;
|
||||
AlignList:=TFPList.Create;
|
||||
try
|
||||
WinControl.CreateControlAlignList(alNone,AlignList,nil);
|
||||
for i:=0 to WinControl.ControlCount-1 do begin
|
||||
Child:=WinControl.Controls[i];
|
||||
if Child.IsControlVisible and IsNotAligned(Child) then
|
||||
AlignList.Add(Child);
|
||||
end;
|
||||
if AlignList.Count=0 then exit;
|
||||
ChildSizing:=TControlChildSizing.Create(nil);
|
||||
Box:=TAutoSizeBox.Create;
|
||||
@ -990,7 +1000,8 @@ procedure TAutoSizeCtrlData.ComputePreferredClientArea(
|
||||
|
||||
if UseCurrentWidth then
|
||||
NewWidth:=Child.Width
|
||||
else if CurPreferredWidth>0 then
|
||||
else if (CurPreferredWidth>0)
|
||||
or ((CurPreferredWidth=0) and (csAutoSize0x0 in Child.ControlStyle)) then
|
||||
NewWidth:=CurPreferredWidth
|
||||
else
|
||||
NewWidth:=Child.GetDefaultWidth;
|
||||
@ -998,7 +1009,8 @@ procedure TAutoSizeCtrlData.ComputePreferredClientArea(
|
||||
|
||||
if UseCurrentHeight then
|
||||
NewHeight:=Child.Height
|
||||
else if CurPreferredHeight>0 then
|
||||
else if (CurPreferredHeight>0)
|
||||
or ((CurPreferredHeight=0) and (csAutoSize0x0 in Child.ControlStyle)) then
|
||||
NewHeight:=CurPreferredHeight
|
||||
else
|
||||
NewHeight:=Child.GetDefaultHeight;
|
||||
@ -1086,10 +1098,13 @@ begin
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
//WriteDebugReport('anchored','');
|
||||
|
||||
SetupNonAlignedChilds(MoveNonAlignedChilds);
|
||||
//WriteDebugReport('nonaligned','');
|
||||
// setup the dependencies for Aligned controls
|
||||
AlignChilds;
|
||||
//WriteDebugReport('aligned','');
|
||||
|
||||
// setup space for dependencies
|
||||
SetupSpace;
|
||||
@ -2482,14 +2497,6 @@ var
|
||||
end;
|
||||
end;
|
||||
|
||||
function IsNotAligned(AControl: TControl): boolean;
|
||||
begin
|
||||
Result:=(AControl.Align=alNone)
|
||||
and (AControl.Anchors=[akLeft,akTop])
|
||||
and (AControl.AnchorSide[akLeft].Control=nil)
|
||||
and (AControl.AnchorSide[akTop].Control=nil);
|
||||
end;
|
||||
|
||||
procedure DoPosition(Control: TControl; AAlign: TAlign; AControlIndex: Integer);
|
||||
var
|
||||
NewLeft, NewTop, NewWidth, NewHeight: Integer;
|
||||
@ -8000,7 +8007,7 @@ end;
|
||||
Calculates the default/preferred width and height for a TWinControl, which is
|
||||
used by the LCL autosizing algorithms as default size. Only positive values
|
||||
are valid. Negative or 0 are treated as undefined and the LCL uses other sizes
|
||||
instead.
|
||||
instead (exception: csAutoSize0x0).
|
||||
TWinControl overrides this:
|
||||
If there are childs, their total preferred size is calculated.
|
||||
If this value can not be computed (e.g. the childs depend too much on their
|
||||
@ -8033,6 +8040,7 @@ begin
|
||||
if HandleAllocated then begin
|
||||
TWSWinControlClass(WidgetSetClass).GetPreferredSize(Self,
|
||||
PreferredWidth, PreferredHeight, WithThemeSpace);
|
||||
//DebugLn(['TWinControl.CalculatePreferredSize WidgetSet ',DbgSName(Self),' Preferred=',PreferredWidth,'x',PreferredHeight]);
|
||||
end;
|
||||
|
||||
// check AdjustClientRect
|
||||
@ -8053,6 +8061,7 @@ begin
|
||||
Layout:=TAutoSizeCtrlData.Create(Self);
|
||||
Layout.ComputePreferredClientArea(false,NewMoveLeft,NewMoveRight,
|
||||
NewClientWidth,NewClientHeight);
|
||||
//Layout.WriteDebugReport('TWinControl.CalculatePreferredSize ',' ');
|
||||
if (NewMoveLeft<>0) or (NewMoveRight<>0) then ;
|
||||
finally
|
||||
Layout.Free;
|
||||
|
Loading…
Reference in New Issue
Block a user