LCL: added controlstyles csAutoSizeKeepChildLeft, csAutoSizeKeepChildTop, TScrollBox: use preferred size even if AutoSize=false

git-svn-id: trunk@26222 -
This commit is contained in:
mattias 2010-06-21 08:10:11 +00:00
parent c36728ab23
commit 5977b88aca
5 changed files with 42 additions and 58 deletions

View File

@ -218,7 +218,9 @@ type
csHasCancelAction, // control implements useful ExecuteCancelAction csHasCancelAction, // control implements useful ExecuteCancelAction
csNoDesignSelectable, // control can not be selected at design time csNoDesignSelectable, // control can not be selected at design time
csOwnedChildrenNotSelectable, // child controls owned by this control are NOT selectable in the designer csOwnedChildrenNotSelectable, // child controls owned by this control are NOT selectable in the designer
csAutoSize0x0 // if the preferred size is 0x0 then control is shrinked ot 0x0 csAutoSize0x0, // if the preferred size is 0x0 then control is shrinked ot 0x0
csAutoSizeKeepChildLeft, // when AutoSize=true do not move children horizontally
csAutoSizeKeepChildTop // when AutoSize=true do not move children vertically
); );
TControlStyle = set of TControlStyleType; TControlStyle = set of TControlStyleType;

View File

@ -175,6 +175,7 @@ type
procedure SetAutoScroll(Value: Boolean); virtual; procedure SetAutoScroll(Value: Boolean); virtual;
procedure Loaded; override; procedure Loaded; override;
property AutoScroll: Boolean read FAutoScroll write SetAutoScroll default False;// auto show/hide scrollbars property AutoScroll: Boolean read FAutoScroll write SetAutoScroll default False;// auto show/hide scrollbars
procedure SetAutoSize(Value: Boolean); override;
public public
constructor Create(TheOwner : TComponent); override; constructor Create(TheOwner : TComponent); override;
destructor Destroy; override; destructor Destroy; override;

View File

@ -237,58 +237,21 @@ procedure TControlScrollBar.AutoCalcRange;
procedure AutoCalcVRange; procedure AutoCalcVRange;
var var
I: Integer;
TmpRange: Longint;
c: TControl;
PreferredWidth: Integer; PreferredWidth: Integer;
PreferredHeight: Integer; PreferredHeight: Integer;
begin begin
if FControl.AutoSize GetPreferredClientRect(PreferredWidth,PreferredHeight);
or ((FControl.Parent<>nil) and (FControl.Parent.ChildSizing.Layout<>cclNone)) then
begin
GetPreferredClientRect(PreferredWidth,PreferredHeight);
TmpRange := PreferredHeight;
end
else begin
TmpRange := 0;
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),' AutoSize=',FControl.AutoSize,' Bounds=',dbgs(FControl.BoundsRect),' Client=',dbgs(FControl.ClientRect),' TmpRange=',TmpRange,' pref=',PreferredWidth,'x',PreferredHeight]); //DebugLn(['AutoCalcVRange ',DbgSName(FControl),' AutoSize=',FControl.AutoSize,' Bounds=',dbgs(FControl.BoundsRect),' Client=',dbgs(FControl.ClientRect),' TmpRange=',TmpRange,' pref=',PreferredWidth,'x',PreferredHeight]);
InternalSetRange(TmpRange); InternalSetRange(PreferredHeight);
end; end;
procedure AutoCalcHRange; procedure AutoCalcHRange;
var var
i: Integer;
TmpRange : Longint;
c: TControl;
PreferredWidth: Integer; PreferredWidth: Integer;
PreferredHeight: Integer; PreferredHeight: Integer;
begin begin
if FControl.AutoSize GetPreferredClientRect(PreferredWidth,PreferredHeight);
or ((FControl.Parent<>nil) and (FControl.Parent.ChildSizing.Layout<>cclNone)) then InternalSetRange(PreferredWidth);
begin
GetPreferredClientRect(PreferredWidth,PreferredHeight);
TmpRange := PreferredWidth;
end
else begin
TmpRange := 0;
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; end;
begin begin

View File

@ -223,6 +223,16 @@ begin
UpdateScrollbars; UpdateScrollbars;
end; end;
procedure TScrollingWinControl.SetAutoSize(Value: Boolean);
begin
if AutoSize=Value then exit;
if Value then
ControlStyle:=ControlStyle-[csAutoSizeKeepChildLeft,csAutoSizeKeepChildTop]
else
ControlStyle:=ControlStyle+[csAutoSizeKeepChildLeft,csAutoSizeKeepChildTop];
inherited SetAutoSize(Value);
end;
procedure TScrollingWinControl.WMVScroll(var Message : TLMVScroll); procedure TScrollingWinControl.WMVScroll(var Message : TLMVScroll);
begin begin
VertScrollbar.ScrollHandler(Message); VertScrollbar.ScrollHandler(Message);
@ -242,7 +252,8 @@ begin
FVertScrollbar := TControlScrollBar.Create(Self, sbVertical); FVertScrollbar := TControlScrollBar.Create(Self, sbVertical);
FHorzScrollbar := TControlScrollBar.Create(Self, sbHorizontal); FHorzScrollbar := TControlScrollBar.Create(Self, sbHorizontal);
ControlStyle := [csAcceptsControls, csClickEvents, csDoubleClicks]; ControlStyle := [csAcceptsControls, csClickEvents, csDoubleClicks,
csAutoSizeKeepChildLeft, csAutoSizeKeepChildTop];
with GetControlClassDefaultSize do with GetControlClassDefaultSize do
SetInitialBounds(0, 0, CX, CY); SetInitialBounds(0, 0, CX, CY);

View File

@ -170,7 +170,8 @@ type
function GetChildren(AControl: TControl): TAutoSizeCtrlData; function GetChildren(AControl: TControl): TAutoSizeCtrlData;
procedure DoMoveNonAlignedChildren(Side: TAnchorKind; procedure DoMoveNonAlignedChildren(Side: TAnchorKind;
var MoveDiff: integer; FindMinimum: boolean); var MoveDiff: integer; FindMinimum: boolean);
procedure SetupNonAlignedChildren(MoveNonAlignedChildren: boolean); procedure SetupNonAlignedChildren(MoveNonAlignedChildrenLeft,
MoveNonAlignedChildrenTop: boolean);
procedure AlignChildren; procedure AlignChildren;
procedure SetupSpace; procedure SetupSpace;
function ComputePositions: boolean;// false if recomputation is needed (a property changed) function ComputePositions: boolean;// false if recomputation is needed (a property changed)
@ -188,7 +189,8 @@ type
constructor Create(AControl: TControl; IsParent: boolean = true); constructor Create(AControl: TControl; IsParent: boolean = true);
destructor Destroy; override; destructor Destroy; override;
procedure Clear; procedure Clear;
procedure ComputePreferredClientArea(MoveNonAlignedChilds: boolean; procedure ComputePreferredClientArea(MoveNonAlignedChildrenLeft,
MoveNonAlignedChildrenTop: boolean;
out MoveNonAlignedToLeft, MoveNonAlignedToTop, out MoveNonAlignedToLeft, MoveNonAlignedToTop,
PreferredClientWidth, PreferredClientHeight: integer); PreferredClientWidth, PreferredClientHeight: integer);
procedure FixControlProperties(Child: TControl); procedure FixControlProperties(Child: TControl);
@ -874,7 +876,8 @@ begin
end; end;
end; end;
procedure TAutoSizeCtrlData.SetupNonAlignedChildren(MoveNonAlignedChildren: boolean); procedure TAutoSizeCtrlData.SetupNonAlignedChildren(MoveNonAlignedChildrenLeft,
MoveNonAlignedChildrenTop: boolean);
var var
ChildSizing: TControlChildSizing; ChildSizing: TControlChildSizing;
Box: TAutoSizeBox; Box: TAutoSizeBox;
@ -897,12 +900,12 @@ begin
MoveDiff:=0; MoveDiff:=0;
DoMoveNonAlignedChildren(akLeft,MoveDiff,true); DoMoveNonAlignedChildren(akLeft,MoveDiff,true);
//DebugLn(['TAutoSizeCtrlData.ComputePreferredClientArea akLeft MoveDiff=',MoveDiff]); //DebugLn(['TAutoSizeCtrlData.ComputePreferredClientArea akLeft MoveDiff=',MoveDiff]);
if not MoveNonAlignedChildren then MoveDiff:=0; if not MoveNonAlignedChildrenLeft then MoveDiff:=0;
DoMoveNonAlignedChildren(akLeft,MoveDiff,false); DoMoveNonAlignedChildren(akLeft,MoveDiff,false);
MoveDiff:=0; MoveDiff:=0;
DoMoveNonAlignedChildren(akTop,MoveDiff,true); DoMoveNonAlignedChildren(akTop,MoveDiff,true);
//DebugLn(['TAutoSizeCtrlData.ComputePreferredClientArea akTop MoveDiff=',MoveDiff]); //DebugLn(['TAutoSizeCtrlData.ComputePreferredClientArea akTop MoveDiff=',MoveDiff]);
if not MoveNonAlignedChildren then MoveDiff:=0; if not MoveNonAlignedChildrenTop then MoveDiff:=0;
DoMoveNonAlignedChildren(akTop,MoveDiff,false); DoMoveNonAlignedChildren(akTop,MoveDiff,false);
end else begin end else begin
// there is an automatic layout for non aligned childs // there is an automatic layout for non aligned childs
@ -960,9 +963,9 @@ begin
end; end;
procedure TAutoSizeCtrlData.ComputePreferredClientArea( procedure TAutoSizeCtrlData.ComputePreferredClientArea(
MoveNonAlignedChilds: boolean; MoveNonAlignedChildrenLeft, MoveNonAlignedChildrenTop: boolean; out
out MoveNonAlignedToLeft, MoveNonAlignedToTop, MoveNonAlignedToLeft, MoveNonAlignedToTop, PreferredClientWidth,
PreferredClientWidth, PreferredClientHeight: integer); PreferredClientHeight: integer);
{ if MoveNonAlignedChilds=true then all non-aligned childs will be moved in { if MoveNonAlignedChilds=true then all non-aligned childs will be moved in
parallel, so that at least one child is positioned left most and one child parallel, so that at least one child is positioned left most and one child
is positioned top most. is positioned top most.
@ -1140,7 +1143,7 @@ begin
end; end;
//WriteDebugReport('anchored',''); //WriteDebugReport('anchored','');
SetupNonAlignedChildren(MoveNonAlignedChilds); SetupNonAlignedChildren(MoveNonAlignedChildrenLeft,MoveNonAlignedChildrenTop);
//WriteDebugReport('nonaligned',''); //WriteDebugReport('nonaligned','');
// setup the dependencies for Aligned controls // setup the dependencies for Aligned controls
AlignChildren; AlignChildren;
@ -1182,7 +1185,7 @@ begin
end; end;
// compute needed MoveNonAlignedToLeft,MoveNonAlignedToTop // compute needed MoveNonAlignedToLeft,MoveNonAlignedToTop
if MoveNonAlignedChilds then if MoveNonAlignedChildrenLeft or MoveNonAlignedChildrenTop then
begin begin
MoveNonAlignedToLeft:=Low(integer); MoveNonAlignedToLeft:=Low(integer);
MoveNonAlignedToTop:=Low(integer); MoveNonAlignedToTop:=Low(integer);
@ -1192,7 +1195,8 @@ begin
ChildData:=Children[Child]; ChildData:=Children[Child];
if not Child.IsControlVisible then continue; if not Child.IsControlVisible then continue;
if not IsNotAligned(Child) then continue; if not IsNotAligned(Child) then continue;
if (ChildData.Sides[akLeft].DistanceState[assddLeftTop]=assdfValid) then if MoveNonAlignedChildrenLeft
and (ChildData.Sides[akLeft].DistanceState[assddLeftTop]=assdfValid) then
MoveNonAlignedToLeft:=Max(MoveNonAlignedToLeft, MoveNonAlignedToLeft:=Max(MoveNonAlignedToLeft,
Child.Left-ChildData.Sides[akLeft].Distance[assddLeftTop]); Child.Left-ChildData.Sides[akLeft].Distance[assddLeftTop]);
{ the below is only correct, if PreferredClientWidth is realized. { the below is only correct, if PreferredClientWidth is realized.
@ -1201,7 +1205,8 @@ begin
Child.Left Child.Left
-(PreferredClientWidth -(PreferredClientWidth
-ChildData.Sides[akLeft].Distance[assddRightBottom]));} -ChildData.Sides[akLeft].Distance[assddRightBottom]));}
if (ChildData.Sides[akTop].DistanceState[assddLeftTop]=assdfValid) then if MoveNonAlignedChildrenTop
and (ChildData.Sides[akTop].DistanceState[assddLeftTop]=assdfValid) then
MoveNonAlignedToTop:=Max(MoveNonAlignedToTop, MoveNonAlignedToTop:=Max(MoveNonAlignedToTop,
Child.Top-ChildData.Sides[akTop].Distance[assddLeftTop]); Child.Top-ChildData.Sides[akTop].Distance[assddLeftTop]);
{ the below is only correct, if PreferredClientWidth is realized. { the below is only correct, if PreferredClientWidth is realized.
@ -3254,8 +3259,10 @@ var
Layout:=nil; Layout:=nil;
try try
Layout:=TAutoSizeCtrlData.Create(Self); Layout:=TAutoSizeCtrlData.Create(Self);
Layout.ComputePreferredClientArea(true,dx,dy, Layout.ComputePreferredClientArea(
NewClientWidth,NewClientHeight); not (csAutoSizeKeepChildLeft in ControlStyle),
not (csAutoSizeKeepChildTop in ControlStyle),
dx,dy,NewClientWidth,NewClientHeight);
if (NewClientWidth<>0) or (NewClientHeight<>0) then ; if (NewClientWidth<>0) or (NewClientHeight<>0) then ;
//if (dx<>0) or (dy<>0) then DebugLn(['GetMoveDiffForNonAlignedChilds ',DbgSName(Self),' dx=',dx,' dy=',dy]); //if (dx<>0) or (dy<>0) then DebugLn(['GetMoveDiffForNonAlignedChilds ',DbgSName(Self),' dx=',dx,' dy=',dy]);
finally finally
@ -7757,7 +7764,7 @@ begin
Layout:=nil; Layout:=nil;
try try
Layout:=TAutoSizeCtrlData.Create(Self); Layout:=TAutoSizeCtrlData.Create(Self);
Layout.ComputePreferredClientArea(false,NewMoveLeft,NewMoveRight, Layout.ComputePreferredClientArea(false,false,NewMoveLeft,NewMoveRight,
NewClientWidth,NewClientHeight); NewClientWidth,NewClientHeight);
//Layout.WriteDebugReport('TWinControl.CalculatePreferredSize ',' '); //Layout.WriteDebugReport('TWinControl.CalculatePreferredSize ',' ');
if (NewMoveLeft<>0) or (NewMoveRight<>0) then ; if (NewMoveLeft<>0) or (NewMoveRight<>0) then ;