LCL: TControl.DoAutoSize: autosizes to peferred size

git-svn-id: trunk@24379 -
This commit is contained in:
mattias 2010-04-03 15:52:01 +00:00
parent 68c75f3577
commit 3729314672
5 changed files with 82 additions and 63 deletions

View File

@ -1074,6 +1074,10 @@ type
function GetControlOrigin: TPoint; virtual;
function IsClientHeightStored: boolean; virtual;
function IsClientWidthStored: boolean; virtual;
{$IFNDEF OldAutoSize}
function WidthIsAnchored: boolean;
function HeightIsAnchored: boolean;
{$ENDIF}
property AutoSizing: Boolean read FAutoSizingSelf;// see Begin/EndAutoSizing
{$IFNDEF OldAutoSize}

View File

@ -2396,10 +2396,26 @@ end;
That's why you should always call AdjustSize instead of DoAutoSize.
------------------------------------------------------------------------------}
procedure TControl.DoAutoSize;
{$IFNDEF OldAutoSize}
var
PreferredWidth: integer;
PreferredHeight: integer;
ResizeWidth: Boolean;
ResizeHeight: Boolean;
{$ENDIF}
begin
//Handled by TWinControl, or other descendants
// handled by TWinControl, or other descendants
{$IFNDEF OldAutoSize}
Exclude(FControlFlags,cfAutoSizeNeeded);
ResizeWidth:=not WidthIsAnchored;
ResizeHeight:=not HeightIsAnchored;
if ResizeWidth or ResizeHeight then begin
PreferredWidth:=0;
PreferredHeight:=0;
GetPreferredSize(PreferredWidth,PreferredHeight);
if (not ResizeWidth) or (PreferredWidth<=0) then PreferredWidth:=Width;
if (not ResizeHeight) or (PreferredHeight<=0) then PreferredHeight:=Height;
SetBoundsKeepBase(Left,Top,PreferredWidth,PreferredHeight);
end;
{$ENDIF}
end;
@ -2419,14 +2435,16 @@ procedure TControl.DoAllAutoSize;
if AControl.AutoSizeDelayed then exit;
if not (cfAutoSizeNeeded in AControl.FControlFlags) then exit;
//DebugLn(['TControl.DoAllAutoSize.AutoSizeControl ',DbgSName(AControl),' AutoSize=',AControl.AutoSize]);
//DebugLn(['TControl.DoAllAutoSize.AutoSizeControl ',DbgSName(AControl),' AutoSize=',AControl.AutoSize,' IsControlVisible=',AControl.IsControlVisible]);
Exclude(AControl.FControlFlags,cfAutoSizeNeeded);
if not IsControlVisible then exit;
if not AControl.IsControlVisible then exit;
if AControl.AutoSize then
AControl.DoAutoSize;
if AControl is TWinControl then begin
// recursive
AWinControl:=TWinControl(AControl);
//DebugLn(['AutoSizeControl ',DbgSName(AWinControl)]);
AWinControl.AlignControl(nil);
for i:=0 to AWinControl.ControlCount-1 do
AutoSizeControl(AWinControl.Controls[i]);
@ -2876,6 +2894,34 @@ begin
Result:=false;
end;
{$IFNDEF OldAutoSize}
function TControl.WidthIsAnchored: boolean;
var
CurAnchors: TAnchors;
begin
CurAnchors:=Anchors;
if Align<>alNone then CurAnchors:=CurAnchors+AnchorAlign[Align];
Result:=(CurAnchors*[akLeft,akRight]=[akLeft,akRight]);
if not Result then begin
if Parent<>nil then
Result:=Parent.ChildSizing.Layout<>cclNone;
end;
end;
function TControl.HeightIsAnchored: boolean;
var
CurAnchors: TAnchors;
begin
CurAnchors:=Anchors;
if Align<>alNone then CurAnchors:=CurAnchors+AnchorAlign[Align];
Result:=(CurAnchors*[akTop,akBottom]=[akTop,akBottom]);
if not Result then begin
if Parent<>nil then
Result:=Parent.ChildSizing.Layout<>cclNone;
end;
end;
{$ENDIF}
procedure TControl.WMCancelMode(var Message: TLMessage);
begin
MouseCapture := False;

View File

@ -540,7 +540,7 @@ begin
PreferredHeight := NewHeight;
end;
{$ENDIF}
DebugLn(['TToolBar.CalculatePreferredSize ',DbgSName(Self),' ',PreferredWidth,'x',PreferredHeight,' Count=',ControlCount]);
//DebugLn(['TToolBar.CalculatePreferredSize ',DbgSName(Self),' ',PreferredWidth,'x',PreferredHeight,' Count=',ControlCount]);
end;
{------------------------------------------------------------------------------
@ -575,15 +575,14 @@ var
PreferredBtnWidth: Integer;
PreferredBtnHeight: Integer;
begin
if (CurControl is TToolButton) and
(TToolButton(CurControl).Style in [tbsButton, tbsDropDown, tbsCheck]) and
(not CurControl.AutoSize) then
if (CurControl is TToolButton) and (not CurControl.AutoSize) then
begin
PreferredBtnWidth := 0;
PreferredBtnHeight := 0;
CurControl.GetPreferredSize(PreferredBtnWidth, PreferredBtnHeight);
NewControlWidth := PreferredBtnWidth;
if NewControlWidth < ButtonWidth then
if (NewControlWidth < ButtonWidth)
and (TToolButton(CurControl).Style in [tbsButton, tbsDropDown, tbsCheck]) then
NewControlWidth := ButtonWidth;
end
else

View File

@ -614,6 +614,7 @@ procedure TToolButton.SetStyle(Value: TToolButtonStyle);
begin
if FStyle = Value then exit;
FStyle := Value;
InvalidatePreferredSize;
if Visible then
UpdateVisibleToolbar;
end;

View File

@ -2476,6 +2476,8 @@ var
r: TRect;
AlignInfo: TAlignInfo; // alCustom
PrefWidth: integer;
PrefHeight: integer;
function ConstraintWidth(NewWidth: integer): Integer;
begin
@ -2585,6 +2587,11 @@ var
NewTop:=Top;
NewWidth:=Width;
NewHeight:=Height;
if AutoSize then begin
GetPreferredSize(PrefWidth,PrefHeight);
if PrefWidth>0 then NewWidth:=PrefWidth;
if PrefHeight>0 then NewHeight:=PrefHeight;
end;
ConstraintWidth(NewLeft,NewWidth);
ConstraintHeight(NewTop,NewHeight);
end;
@ -3039,6 +3046,7 @@ var
OldRemainingBorderSpace: TRect;
MaxTries: LongInt;
begin
//DebugLn(['TWinControl.AlignControls ',DbgSName(Self),' ',not (wcfAligningControls in FWinControlFlags)]);
if wcfAligningControls in FWinControlFlags then exit;
Include(FWinControlFlags,wcfAligningControls);
try
@ -3225,43 +3233,7 @@ end;
procedure TWinControl.DoAutoSize;
var
HasVisibleChilds: boolean;
function WidthAnchored(CurAnchors: TAnchors): boolean;
begin
Result:=(CurAnchors*[akLeft,akRight]=[akLeft,akRight]);
end;
function WidthDependsOnChilds: boolean;
begin
Result:=false;
end;
function WidthDependsOnParent: boolean;
begin
if Parent=nil then
Result:=false
else
Result:=(Parent.ChildSizing.Layout<>cclNone);
end;
function HeightAnchored(CurAnchors: TAnchors): boolean;
begin
Result:=(CurAnchors*[akTop,akBottom]=[akTop,akBottom]);
end;
function HeightDependsOnChilds: boolean;
begin
Result:=false;
end;
function HeightDependsOnParent: boolean;
begin
if Parent=nil then
Result:=false
else
Result:=Parent.ChildSizing.Layout<>cclNone;
end;
procedure GetMoveDiffForNonAlignedChilds(const CurClientRect: TRect;
out dx, dy: integer);
// how much can non-aligned-childs be moved up and left
@ -3348,12 +3320,8 @@ begin
CurAnchors:=Anchors;
if Align<>alNone then CurAnchors:=CurAnchors+AnchorAlign[Align];
WidthIsFixed:=WidthAnchored(CurAnchors)
or WidthDependsOnChilds
or WidthDependsOnParent;
HeightIsFixed:=HeightAnchored(CurAnchors)
or HeightDependsOnChilds
or HeightDependsOnParent;
WidthIsFixed:=WidthIsAnchored;
HeightIsFixed:=HeightIsAnchored;
// move free childs as much as possible to left and top (all free childs the same)
if HasVisibleChilds then begin
@ -6158,13 +6126,9 @@ begin
end;
end;
{$ELSE}
if AutoSizeDelayed then begin
AdjustSize;
exit;
end;
// only called by DoAllAutoSize, so no check needed
{$ENDIF}
{$IFDEF OldAutoSize}
DisableAlign;
try
@ -6185,13 +6149,18 @@ begin
end;
{$ELSE}
ARect:= GetLogicalClientRect;
AlignControls(AControl, ARect);
// some widgetsets updates their clientrect when the first child was moved
// do a second pass if ClientRect changed
NewRect:=GetLogicalClientRect;
if not CompareRect(@ARect,@NewRect) then
AlignControls(AControl, NewRect);
DisableAlign;
try
ARect:= GetLogicalClientRect;
AlignControls(AControl, ARect);
// some widgetsets updates their clientrect when the first child was moved
// do a second pass if ClientRect changed
NewRect:=GetLogicalClientRect;
if not CompareRect(@ARect,@NewRect) then
AlignControls(AControl, NewRect);
finally
EnableAlign;
end;
{$ENDIF}
end;