From 37293146728fd422ba55e08420a7ef19c5f7976c Mon Sep 17 00:00:00 2001 From: mattias Date: Sat, 3 Apr 2010 15:52:01 +0000 Subject: [PATCH] LCL: TControl.DoAutoSize: autosizes to peferred size git-svn-id: trunk@24379 - --- lcl/controls.pp | 4 ++ lcl/include/control.inc | 54 ++++++++++++++++++++++++-- lcl/include/toolbar.inc | 9 ++--- lcl/include/toolbutton.inc | 1 + lcl/include/wincontrol.inc | 77 ++++++++++++-------------------------- 5 files changed, 82 insertions(+), 63 deletions(-) diff --git a/lcl/controls.pp b/lcl/controls.pp index 2488957dcf..b11471c6a6 100644 --- a/lcl/controls.pp +++ b/lcl/controls.pp @@ -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} diff --git a/lcl/include/control.inc b/lcl/include/control.inc index 70f9e790ae..6730922819 100644 --- a/lcl/include/control.inc +++ b/lcl/include/control.inc @@ -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; diff --git a/lcl/include/toolbar.inc b/lcl/include/toolbar.inc index 98c5159880..c614dcbc1f 100644 --- a/lcl/include/toolbar.inc +++ b/lcl/include/toolbar.inc @@ -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 diff --git a/lcl/include/toolbutton.inc b/lcl/include/toolbutton.inc index 6ff41d744f..aec1edce14 100644 --- a/lcl/include/toolbutton.inc +++ b/lcl/include/toolbutton.inc @@ -614,6 +614,7 @@ procedure TToolButton.SetStyle(Value: TToolButtonStyle); begin if FStyle = Value then exit; FStyle := Value; + InvalidatePreferredSize; if Visible then UpdateVisibleToolbar; end; diff --git a/lcl/include/wincontrol.inc b/lcl/include/wincontrol.inc index e376a447a2..669bfaea00 100644 --- a/lcl/include/wincontrol.inc +++ b/lcl/include/wincontrol.inc @@ -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;