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 GetControlOrigin: TPoint; virtual;
function IsClientHeightStored: boolean; virtual; function IsClientHeightStored: boolean; virtual;
function IsClientWidthStored: boolean; virtual; function IsClientWidthStored: boolean; virtual;
{$IFNDEF OldAutoSize}
function WidthIsAnchored: boolean;
function HeightIsAnchored: boolean;
{$ENDIF}
property AutoSizing: Boolean read FAutoSizingSelf;// see Begin/EndAutoSizing property AutoSizing: Boolean read FAutoSizingSelf;// see Begin/EndAutoSizing
{$IFNDEF OldAutoSize} {$IFNDEF OldAutoSize}

View File

@ -2396,10 +2396,26 @@ end;
That's why you should always call AdjustSize instead of DoAutoSize. That's why you should always call AdjustSize instead of DoAutoSize.
------------------------------------------------------------------------------} ------------------------------------------------------------------------------}
procedure TControl.DoAutoSize; procedure TControl.DoAutoSize;
{$IFNDEF OldAutoSize}
var
PreferredWidth: integer;
PreferredHeight: integer;
ResizeWidth: Boolean;
ResizeHeight: Boolean;
{$ENDIF}
begin begin
//Handled by TWinControl, or other descendants // handled by TWinControl, or other descendants
{$IFNDEF OldAutoSize} {$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} {$ENDIF}
end; end;
@ -2419,14 +2435,16 @@ procedure TControl.DoAllAutoSize;
if AControl.AutoSizeDelayed then exit; if AControl.AutoSizeDelayed then exit;
if not (cfAutoSizeNeeded in AControl.FControlFlags) 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); Exclude(AControl.FControlFlags,cfAutoSizeNeeded);
if not IsControlVisible then exit; if not AControl.IsControlVisible then exit;
if AControl.AutoSize then if AControl.AutoSize then
AControl.DoAutoSize; AControl.DoAutoSize;
if AControl is TWinControl then begin if AControl is TWinControl then begin
// recursive
AWinControl:=TWinControl(AControl); AWinControl:=TWinControl(AControl);
//DebugLn(['AutoSizeControl ',DbgSName(AWinControl)]);
AWinControl.AlignControl(nil); AWinControl.AlignControl(nil);
for i:=0 to AWinControl.ControlCount-1 do for i:=0 to AWinControl.ControlCount-1 do
AutoSizeControl(AWinControl.Controls[i]); AutoSizeControl(AWinControl.Controls[i]);
@ -2876,6 +2894,34 @@ begin
Result:=false; Result:=false;
end; 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); procedure TControl.WMCancelMode(var Message: TLMessage);
begin begin
MouseCapture := False; MouseCapture := False;

View File

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

View File

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

View File

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