LCL: started new autosizing phases

git-svn-id: trunk@21491 -
This commit is contained in:
mattias 2009-08-30 21:30:57 +00:00
parent 21c19e81d2
commit 7799ac78c6
5 changed files with 610 additions and 132 deletions

View File

@ -221,7 +221,11 @@ type
csClicked,
csPalette,
csReadingState,
{$IFDEF NewAutoSize}
// deprecated
{$ELSE}
csAlignmentNeeded,
{$ENDIF}
csFocusing,
csCreating,
csPaintCopy,
@ -782,7 +786,12 @@ type
var Handled: Boolean) of object;
TControlFlag = (
{$IFDEF NewAutoSize}
cfLoading, // set by TControl.ReadState, unset by TControl.Loaded when all on form finished loading
{$ELSE}
// obsolete
cfRequestAlignNeeded,
{$ENDIF}
cfAutoSizeNeeded,
cfLeftLoaded, // cfLeftLoaded is set, when 'Left' is set during loading.
cfTopLoaded,
@ -828,7 +837,7 @@ type
FAnchors: TAnchors;
FAnchorSides: array[TAnchorKind] of TAnchorSide;
FAnchoredControls: TFPList; // list of TControl anchored to this control
FAutoSizingLockCount: Integer;
FAutoSizingLockCount: Integer; // in/decreased by DisableAutoSizing/EnableAutoSizing
FBaseBounds: TRect;
FBaseBoundsLock: integer;
FBaseParentClientSize: TPoint;
@ -906,19 +915,25 @@ type
FUndockWidth: Integer;
FWidth: Integer;
FWindowProc: TWndMethod;
//boolean fields
//boolean fields, keep together to save some bytes
FIsControl: Boolean;
FShowHint: Boolean;
FParentColor: Boolean;
FParentFont: Boolean;
FParentShowHint: Boolean;
FAutoSize: Boolean;
FAutoSizing: Boolean;
{$IFDEF NewAutoSize}
fAutoSizingAll: boolean;
{$ENDIF}
FAutoSizingSelf: Boolean;
FEnabled: Boolean;
FMouseEntered: boolean;
FVisible: Boolean;
function CaptureMouseButtonsIsStored: boolean;
procedure DoActionChange(Sender: TObject);
{$IFDEF NewAutoSize}
function GetAutoSizingAll: Boolean;
{$ENDIF}
function GetAnchorSide(Kind: TAnchorKind): TAnchorSide;
function GetAnchorSideIndex(Index: integer): TAnchorSide;
function GetAnchoredControls(Index: integer): TControl;
@ -983,8 +998,11 @@ type
protected
// sizing/aligning
procedure DoAutoSize; virtual;
procedure BeginAutoSizing;
procedure EndAutoSizing;
{$IFDEF NewAutoSize}
procedure DoAllAutoSize; virtual; // while autosize needed call DoAutoSize, used by AdjustSize and EnableAutoSizing
{$ENDIF}
procedure BeginAutoSizing; // set AutoSizing=true, can be used to prevent circles
procedure EndAutoSizing; // set AutoSizing=false
function AutoSizeCanStart: boolean; virtual;
procedure AnchorSideChanged(TheAnchorSide: TAnchorSide); virtual;
procedure ForeignAnchorSideChanged(TheAnchorSide: TAnchorSide;
@ -1027,7 +1045,10 @@ type
function IsClientHeightStored: boolean; virtual;
function IsClientWidthStored: boolean; virtual;
property AutoSizing: Boolean read FAutoSizing;
property AutoSizing: Boolean read FAutoSizingSelf;// see Begin/EndAutoSizing
{$IFDEF NewAutoSize}
property AutoSizingAll: Boolean read GetAutoSizingAll;// set in DoAllAutoSize
{$ENDIF}
property AutoSizingLockCount: Integer read FAutoSizingLockCount;
protected
// protected messages
@ -1113,7 +1134,9 @@ type
procedure Changed;
function GetPalette: HPalette; virtual;
function ChildClassAllowed(ChildClass: TClass): boolean; virtual;
procedure ReadState(Reader: TReader); override; // called
procedure Loaded; override;
procedure LoadedAll; virtual; // called when all controls were Loaded and lost their csLoading
procedure DefineProperties(Filer: TFiler); override;
procedure AssignTo(Dest: TPersistent); override;
procedure FormEndUpdated; virtual;
@ -1539,7 +1562,11 @@ type
wcfClientRectNeedsUpdate,
wcfColorChanged,
wcfFontChanged, // Set if font was changed before handle creation
{$IFDEF NewAutoSize}
// obsolete
{$ELSE}
wcfReAlignNeeded,
{$ENDIF}
wcfAligningControls,
wcfEraseBackground,
wcfCreatingHandle, // Set while constructing the handle of this control
@ -1607,7 +1634,10 @@ type
FHandle: Hwnd;
FTabOrder: integer;
FTabList: TFPList;
// keep small variables together to save some bytes
{$IFNDEF NewAutoSize}
FAlignLevel: Word;
{$ENDIF}
FTabStop: Boolean;
FShowing: Boolean;
FDoubleBuffered: Boolean;
@ -1652,20 +1682,25 @@ type
function DoAlignChildControls(TheAlign: TAlign; AControl: TControl;
AControlList: TFPList; var ARect: TRect): Boolean; virtual;
procedure DoChildSizingChange(Sender: TObject); virtual;
{$IFNDEF NewAutoSize}
procedure ResizeDelayedAutoSizeChildren; virtual;
{$ENDIF}
procedure InvalidatePreferredChildSizes;
function CanTab: Boolean; override;
function IsClientHeightStored: boolean; override;
function IsClientWidthStored: boolean; override;
procedure DoSendShowHideToInterface; virtual;
procedure DoSendShowHideToInterface; virtual; // called by TWinControl.CMShowingChanged
procedure ControlsAligned; virtual;// called by AlignControls after aligning controls
procedure DoSendBoundsToInterface; virtual;
procedure DoSendBoundsToInterface; virtual; // called by RealizeBounds
procedure RealizeBounds; virtual;// checks for changes and calls DoSendBoundsToInterface
procedure RealizeBoundsRecursive;
procedure CreateSubClass(var Params: TCreateParams;ControlClassName: PChar);
procedure RealizeBoundsRecursive; // called by DoAllAutoSize
procedure CreateSubClass(var Params: TCreateParams; ControlClassName: PChar);
procedure DoConstraintsChange(Sender: TObject); override;
procedure DoSetBounds(ALeft, ATop, AWidth, AHeight: integer); override;
procedure DoAutoSize; override;
{$IFDEF NewAutoSize}
procedure DoAllAutoSize; override;
{$ENDIF}
procedure CalculatePreferredSize(var PreferredWidth,
PreferredHeight: integer;
WithThemeSpace: Boolean); override;
@ -1680,7 +1715,7 @@ type
procedure CMBiDiModeChanged(var Message: TLMessage); message CM_BIDIMODECHANGED;
procedure CMBorderChanged(var Message: TLMessage); message CM_BORDERCHANGED;
procedure CMEnabledChanged(var Message: TLMessage); message CM_ENABLEDCHANGED;
procedure CMShowingChanged(var Message: TLMessage); message CM_SHOWINGCHANGED;
procedure CMShowingChanged(var Message: TLMessage); message CM_SHOWINGCHANGED; // called by TWinControl.UpdateShowing
procedure CMShowHintChanged(var Message: TLMessage); message CM_SHOWHINTCHANGED;
procedure CMVisibleChanged(var TheMessage: TLMessage); message CM_VISIBLECHANGED;
procedure WMEraseBkgnd(var Message: TLMEraseBkgnd); message LM_ERASEBKGND;
@ -1785,7 +1820,7 @@ type
procedure SetChildZPosition(const AChild: TControl; const APosition: Integer);
procedure ShowControl(AControl: TControl); virtual;
procedure UpdateControlState;
procedure UpdateShowing; virtual;
procedure UpdateShowing; virtual; // checks control's handle visibility, called by UpdateControlState and CreateWnd
procedure WndProc(var Message: TLMessage); override;
procedure WSSetText(const AText: String); virtual;
protected
@ -1824,17 +1859,17 @@ type
property OnKeyUp: TKeyEvent read FOnKeyUp write FOnKeyUp;
property OnUnDock: TUnDockEvent read FOnUnDock write FOnUnDock;
property OnUTF8KeyPress: TUTF8KeyPressEvent read FOnUTF8KeyPress write FOnUTF8KeyPress;
property Showing: Boolean read FShowing;
property Showing: Boolean read FShowing; // handle visible
property UseDockManager: Boolean read FUseDockManager
write SetUseDockManager default False;
property VisibleDockClientCount: Integer read GetVisibleDockClientCount;
public
// size, position, bounds
function AutoSizeDelayed: boolean; override;
procedure BeginUpdateBounds;
procedure EndUpdateBounds;
procedure LockRealizeBounds;
procedure UnlockRealizeBounds;
procedure BeginUpdateBounds; // disable SetBounds
procedure EndUpdateBounds; // enable SetBounds
procedure LockRealizeBounds; // disable sending bounds to widgetset
procedure UnlockRealizeBounds; // enable sending bounds to widgetset, changes will now be sent
function ControlAtPos(const Pos: TPoint; AllowDisabled: Boolean): TControl;
function ControlAtPos(const Pos: TPoint;
AllowDisabled, AllowWinControls: Boolean): TControl;

View File

@ -40,6 +40,16 @@
------------------------------------------------------------------------------}
procedure TControl.Adjustsize;
begin
{$IFDEF NewAutoSize}
Include(FControlFlags,cfAutoSizeNeeded);
if IsControlVisible then
begin
if Parent<>nil then
Parent.AdjustSize
else
DoAllAutoSize;
end;
{$ELSE}
//debugln(['TControl.AdjustSize START ',DbgSName(Self),' AutoSizeCanStart=',AutoSizeCanStart,' AutoSizeDelayed=',AutoSizeDelayed]);
if (not AutoSizeCanStart) or AutoSizeDelayed then begin
//debugln('TControl.AdjustSize AutoSizeDelayed ',DbgSName(Self));
@ -49,6 +59,7 @@ begin
//debugln(['TControl.AdjustSize DoAutoSize ',DbgSName(Self)]);
DoAutoSize;
Exclude(FControlFlags,cfAutoSizeNeeded);
{$ENDIF}
end;
{------------------------------------------------------------------------------
@ -83,8 +94,8 @@ procedure TControl.BeginAutoSizing;
RaiseGDBException('TControl.BeginAutoSizing');
end;
begin
if FAutoSizing then Error;
FAutoSizing := True;
if FAutoSizingSelf then Error;
FAutoSizingSelf := True;
end;
{------------------------------------------------------------------------------
@ -354,6 +365,18 @@ begin
// change base bounds
// (base bounds are the base for the automatic resizing)
UpdateAnchorRules;
{$IFDEF NewAutoSize}
// lock size messages
inc(FSizeLock);
try
// notify before autosizing
BoundsChanged;
if PosSizeKept then exit;
AdjustSize;
finally
dec(FSizeLock);
end;
{$ELSE}
// lock the base bounds while automatic resizing
LockBaseBounds;
// lock size messages
@ -391,6 +414,7 @@ begin
dec(FSizeLock);
UnlockBaseBounds;
end;
{$ENDIF}
if PosSizeKept then exit;
// send messages, if this is the top level call
@ -1296,7 +1320,10 @@ begin
p:=Parent;
while (p<>nil) do begin
if (wcfAligningControls in p.FWinControlFlags)
or (p.FAlignLevel>0) then
{$IFNDEF NewAutoSize}
or (p.FAlignLevel>0)
{$ENDIF}
then
exit(true);
p:=p.Parent;
end;
@ -1404,6 +1431,16 @@ begin
Result := TControl(FAnchoredControls[Index]);
end;
{$IFDEF NewAutoSize}
function TControl.GetAutoSizingAll: Boolean;
begin
if Parent<>nil then
Result:=Parent.AutoSizingAll
else
Result:=fAutoSizingAll;
end;
{$ENDIF}
{------------------------------------------------------------------------------
TControl GetClientRect
@ -2304,8 +2341,50 @@ end;
procedure TControl.DoAutoSize;
begin
//Handled by TWinControl, or other descendants
Exclude(FControlFlags,cfAutoSizeNeeded);
end;
{------------------------------------------------------------------------------
TControl DoAllAutoSize
Run DoAutoSize until done.
------------------------------------------------------------------------------}
{$IFDEF NewAutoSize}
procedure TControl.DoAllAutoSize;
procedure AutoSizeControl(AControl: TControl);
var
AWinControl: TWinControl;
i: Integer;
begin
if AControl.AutoSizeDelayed then exit;
if not (cfAutoSizeNeeded in AControl.FControlFlags) then exit;
Exclude(AControl.FControlFlags,cfAutoSizeNeeded);
if AutoSize then
DoAutoSize;
if AControl is TWinControl then begin
AWinControl:=TWinControl(AControl);
AWinControl.AlignControl(nil);
for i:=0 to AWinControl.ControlCount-1 do
AutoSizeControl(AWinControl.Controls[i]);
end;
end;
begin
if Parent<>nil then raise Exception.Create('TControl.DoAllAutoSize Parent<>nil');
if AutoSizingAll then exit;
fAutoSizingAll:=true;
try
while (not AutoSizeDelayed)
and (cfAutoSizeNeeded in FControlFlags) do
AutoSizeControl(Self);
finally
fAutoSizingAll:=false;
end;
end;
{$ENDIF}
procedure TControl.AnchorSideChanged(TheAnchorSide: TAnchorSide);
begin
//debugln('TControl.AnchorSideChanged ',DbgSName(Self));
@ -2383,6 +2462,9 @@ begin
Result:=(FAutoSizingLockCount>0)
// no autosize during loading or destruction
or ([csLoading,csDestroying]*ComponentState<>[])
{$IFDEF NewAutoSize}
or (cfLoading in FControlFlags)
{$ENDIF}
// no autosize for invisible controls
or (not IsControlVisible)
// if there is no parent, then this control is not visible
@ -2861,6 +2943,59 @@ begin
end;
procedure TControl.Loaded;
{$IFDEF NewAutoSize}
function FindLoadingControl(AControl: TControl): TControl;
var
i: Integer;
AWinControl: TWinControl;
begin
if csLoading in AControl.ComponentState then exit(AControl);
if AControl is TWinControl then begin
AWinControl:=TWinControl(AControl);
for i:=0 to AWinControl.ControlCount-1 do
begin
Result:=FindLoadingControl(AWinControl.Controls[i]);
if Result<>nil then exit;
end;
end;
Result:=nil;
end;
procedure ClearLoadingFlags(AControl: TControl);
var
i: Integer;
AWinControl: TWinControl;
begin
Exclude(AControl.FControlFlags,cfLoading);
if AControl is TWinControl then begin
AWinControl:=TWinControl(AControl);
for i:=0 to AWinControl.ControlCount-1 do
ClearLoadingFlags(AWinControl.Controls[i]);
end;
end;
procedure CheckLoading(AControl: TControl);
var
TopParent: TControl;
begin
TopParent:=AControl;
while (TopParent.Parent<>nil)
and (cfLoading in TopParent.Parent.FControlFlags) do
TopParent:=TopParent.Parent;
if FindLoadingControl(TopParent)<>nil then exit;
// all components on the form finished loading
ClearLoadingFlags(TopParent);
// call LoadedAll
DisableAutoSizing;
try
AControl.LoadedAll;
finally
EnableAutoSizing;
end;
end;
{$ENDIF}
var
UseClientWidthForWidth: boolean;
UseClientHeightForHeight: boolean;
@ -2868,7 +3003,7 @@ var
NewHeight: LongInt;
begin
inherited Loaded;
{DebugLn(['TControl.Loaded A ',DbgSName(Self),
' LoadedClientWidth=',cfClientWidthLoaded in FControlFlags,'=',FLoadedClientSize.X,
' LoadedClientHeight=',cfClientHeightLoaded in FControlFlags,'=',FLoadedClientSize.Y,
@ -2918,17 +3053,34 @@ begin
UpdateBaseBounds(true,true,true);
{$IFNDEF NewAutoSize}
// obsolete
// align this control and the brothers
if cfRequestAlignNeeded in FControlFlags then
RequestAlign;
// autosize this control
if cfAutoSizeNeeded in FControlFlags then
AdjustSize;
{$ENDIF}
// store designed width and height for undocking
FUndockHeight := Height;
FUndockWidth := Width;
if Action <> nil then ActionChange(Action, True);
{$IFDEF NewAutoSize}
CheckLoading(Self);
{$ELSE}
CheckOnChangeBounds;
{$ENDIF}
end;
procedure TControl.LoadedAll;
begin
AdjustSize;
Resize;
CheckOnChangeBounds;
end;
@ -2961,6 +3113,21 @@ begin
else inherited AssignTo(Dest);
end;
procedure TControl.ReadState(Reader: TReader);
begin
{$IFDEF NewAutoSize}
Include(FControlFlags,cfLoading);
DisableAutoSizing;
try
{$ENDIF}
inherited ReadState(Reader);
{$IFDEF NewAutoSize}
finally
EnableAutoSizing;
end;
{$ENDIF}
end;
procedure TControl.FormEndUpdated;
// called when control is on a form and EndFormUpdate reached 0
// it is called recursively
@ -3025,6 +3192,9 @@ end;
------------------------------------------------------------------------------}
procedure TControl.RequestAlign;
begin
{$IFDEF NewAutoSize}
AdjustSize;
{$ELSE}
if (Parent = nil) or (csDestroying in ComponentState) then exit;
if (csLoading in ComponentState) or (not Parent.HandleAllocated) then begin
//debugln('TControl.RequestAlign csLoading or not HandleAllocated ',DbgSName(Self));
@ -3034,6 +3204,7 @@ begin
//debugln('TControl.RequestAlign AlignControl ',DbgSName(Self));
Parent.AlignControl(Self);
Exclude(FControlFlags,cfRequestAlignNeeded);
{$ENDIF}
end;
procedure TControl.UpdateBaseBounds(StoreBounds,
@ -3286,13 +3457,22 @@ end;
procedure TControl.SetParent(NewParent: TWinControl);
begin
if FParent = NewParent then exit;
CheckNewParent(NewParent);
if FParent <> nil then FParent.RemoveControl(Self);
if cfBoundsRectForNewParentValid in FControlFlags then begin
Exclude(FControlFlags,cfBoundsRectForNewParentValid);
BoundsRect:=BoundsRectForNewParent;
{$IFDEF NewAutoSize}
DisableAutoSizing;
try
{$ENDIF}
CheckNewParent(NewParent);
if FParent <> nil then FParent.RemoveControl(Self);
if cfBoundsRectForNewParentValid in FControlFlags then begin
Exclude(FControlFlags,cfBoundsRectForNewParentValid);
BoundsRect:=BoundsRectForNewParent;
end;
if NewParent <> nil then NewParent.InsertControl(Self);
{$IFDEF NewAutoSize}
finally
EnableAutoSizing;
end;
if NewParent <> nil then NewParent.InsertControl(Self);
{$ENDIF}
end;
{------------------------------------------------------------------------------
@ -3460,39 +3640,65 @@ begin
if FVisible <> Value then
begin
//DebugLn(['TControl.SetVisible ',DbgSName(Self),' NewVisible=',Value]);
VisibleChanging;
FVisible := Value;
{$IFDEF NewAutoSize}
DisableAutoSizing;
try
Perform(CM_VISIBLECHANGED, WParam(Ord(Value)), 0);
Include(FControlFlags, cfRequestAlignNeeded);
if (Self is TWinControl) then
AsWincontrol := TWinControl(Self)
else
AsWincontrol := nil;
// resize parent if it has autosize
if (Parent <> nil) and Parent.AutoSize then
begin
Parent.InvalidatePreferredSize;
Parent.AdjustSize;
end;
if FVisible then
begin
if AsWincontrol <> nil then begin
{$ENDIF}
VisibleChanging;
FVisible := Value;
try
// create/destroy handle
Perform(CM_VISIBLECHANGED, WParam(Ord(Value)), 0);// see TWinControl.CMVisibleChanged
if (Self is TWinControl) then
AsWincontrol := TWinControl(Self)
else
AsWincontrol := nil;
{$IFDEF NewAutoSize}
InvalidatePreferredSize;
if AsWincontrol <> nil then
AsWincontrol.InvalidatePreferredChildSizes;
Include(AsWincontrol.FWinControlFlags, wcfReAlignNeeded);
end;
AdjustSize;
if (AsWincontrol <> nil) and (wcfReAlignNeeded in AsWincontrol.FWinControlFlags) then
AsWincontrol.ReAlign;
if (not Visible) and (Parent<>nil) then
begin
// control became invisible, so AdjustSize was not propagated
// propagate
Parent.InvalidatePreferredSize;
Parent.AdjustSize;
end;
{$ELSE}
Include(FControlFlags, cfRequestAlignNeeded);
// resize parent if it has autosize
if (Parent <> nil) and Parent.AutoSize then
begin
Parent.InvalidatePreferredSize;
Parent.AdjustSize;
end;
if FVisible then
begin
// control became visible
if AsWincontrol <> nil then begin
AsWincontrol.InvalidatePreferredChildSizes;
Include(AsWincontrol.FWinControlFlags, wcfReAlignNeeded);
end;
AdjustSize;
if (AsWincontrol <> nil) and (wcfReAlignNeeded in AsWincontrol.FWinControlFlags) then
AsWincontrol.ReAlign;
end;
if cfRequestAlignNeeded in FControlFlags then
RequestAlign;
//DebugLn(['TControl.SetVisible ',dbgsName(AsWincontrol)]);
if FVisible and (AsWincontrol <> nil) then
AsWincontrol.ResizeDelayedAutoSizeChildren;
{$ENDIF}
finally
VisibleChanged;
end;
if cfRequestAlignNeeded in FControlFlags then
RequestAlign;
//DebugLn(['TControl.SetVisible ',dbgsName(AsWincontrol)]);
if FVisible and (AsWincontrol <> nil) then
AsWincontrol.ResizeDelayedAutoSizeChildren;
{$IFDEF NewAutoSize}
finally
VisibleChanged;
EnableAutoSizing;
end;
{$ENDIF}
end;
if (csLoading in ComponentState) then
ControlState := ControlState + [csVisibleSetInLoading];
@ -4465,6 +4671,9 @@ begin
while AControl<>nil do begin
Exclude(AControl.FControlFlags,cfPreferredSizeValid);
Exclude(AControl.FControlFlags,cfPreferredMinSizeValid);
{$IFDEF NewAutoSize}
if not AControl.IsControlVisible then break;
{$ENDIF}
AControl:=AControl.Parent;
end;
end;
@ -4500,11 +4709,20 @@ end;
procedure TControl.DisableAutoSizing;
begin
{$IFDEF NewAutoSize}
inc(FAutoSizingLockCount);
if FAutoSizingLockCount=1 then
begin
if Parent<>nil then
Parent.DisableAutoSizing;
end;
{$ELSE}
inc(FAutoSizingLockCount);
{$ENDIF}
end;
procedure TControl.EnableAutoSizing;
{$IFNDEF NewAutoSize}
procedure AdjustSizeRecursive(AControl: TControl);
var
AWinControl: TWinControl;
@ -4519,22 +4737,40 @@ procedure TControl.EnableAutoSizing;
AdjustSizeRecursive(TControl(AWincontrol.FWinControls[i]));
end;
end;
{$ENDIF}
begin
if FAutoSizingLockCount<=0 then RaiseGDBException('TControl.EnableAutoSizing');
{$IFDEF NewAutoSize}
dec(FAutoSizingLockCount);
if (FAutoSizingLockCount=0) then
begin
if (Parent<>nil) then
Parent.EnableAutoSizing
else
DoAllAutoSize;
end;
{$ELSE}
dec(FAutoSizingLockCount);
if FAutoSizingLockCount=0 then
AdjustSizeRecursive(Self);
{$ENDIF}
end;
procedure TControl.EndAutoSizing;
{$IFNDEF NewAutoSize}
procedure Error;
begin
RaiseGDBException('TControl.EndAutoSizing');
end;
{$ENDIF}
begin
if not FAutoSizing then Error;
FAutoSizing := False;
{$IFDEF NewAutoSize}
EnableAutoSizing;
{$ELSE}
if not FAutoSizingSelf then Error;
FAutoSizingSelf := False;
{$ENDIF}
end;
{------------------------------------------------------------------------------

View File

@ -564,28 +564,41 @@ end;
procedure TCustomNoteBook.AddRemovePageHandle(APage: TCustomPage);
begin
if (not (csDestroying in APage.ComponentState))
and (APage.TabVisible or (csDesigning in ComponentState)) then begin
{$IFDEF NOTEBOOK_DEBUG}
DebugLn(['TCustomNoteBook.AddRemovePageHandle ADD ',DbgSName(APage),' pfAdded=',pfAdded in APage.FFlags]);
{$ENDIF}
if (pfAdded in APage.FFlags) then exit;
Include(APage.FFlags,pfAdding);
TWSCustomNotebookClass(WidgetSetClass).AddPage(Self, APage, APage.VisibleIndex);
APage.FFlags:=APage.FFlags+[pfAdded]-[pfAdding];
APage.ResizeDelayedAutoSizeChildren
end else begin
{$IFDEF NOTEBOOK_DEBUG}
DebugLn(['TCustomNoteBook.AddRemovePageHandle REMOVE ',DbgSName(APage),' pfAdded=',pfAdded in APage.FFlags]);
{$ENDIF}
if not (pfAdded in APage.FFlags) or (pfRemoving in APage.FFlags) then
exit;
APage.FFlags := APage.FFlags - [pfAdded] + [pfRemoving];
TWSCustomNotebookClass(WidgetSetClass).RemovePage(Self, APage.VisibleIndex);
if APage.HandleAllocated then
APage.DestroyHandle;
Exclude(APage.FFlags, pfRemoving);
{$IFDEF NewAutoSize}
DisableAutoSizing;
try
{$ENDIF}
if (not (csDestroying in APage.ComponentState))
and (APage.TabVisible or (csDesigning in ComponentState)) then begin
{$IFDEF NOTEBOOK_DEBUG}
DebugLn(['TCustomNoteBook.AddRemovePageHandle ADD ',DbgSName(APage),' pfAdded=',pfAdded in APage.FFlags]);
{$ENDIF}
if (pfAdded in APage.FFlags) then exit;
Include(APage.FFlags,pfAdding);
TWSCustomNotebookClass(WidgetSetClass).AddPage(Self, APage, APage.VisibleIndex);
APage.FFlags:=APage.FFlags+[pfAdded]-[pfAdding];
{$IFDEF NewAutoSize}
APage.AdjustSize;
{$ELSE}
APage.ResizeDelayedAutoSizeChildren
{$ENDIF}
end else begin
{$IFDEF NOTEBOOK_DEBUG}
DebugLn(['TCustomNoteBook.AddRemovePageHandle REMOVE ',DbgSName(APage),' pfAdded=',pfAdded in APage.FFlags]);
{$ENDIF}
if not (pfAdded in APage.FFlags) or (pfRemoving in APage.FFlags) then
exit;
APage.FFlags := APage.FFlags - [pfAdded] + [pfRemoving];
TWSCustomNotebookClass(WidgetSetClass).RemovePage(Self, APage.VisibleIndex);
if APage.HandleAllocated then
APage.DestroyHandle;
Exclude(APage.FFlags, pfRemoving);
end;
{$IFDEF NewAutoSize}
finally
EnableAutoSizing;
end;
{$ENDIF}
end;
procedure TCustomNotebook.RemovePage(Index: Integer);

View File

@ -440,7 +440,6 @@ var
NewHeight: Integer;
begin
if AutoSizing then Exit; // we shouldn't come here in the first place
BeginAutoSizing;
try
WrapButtons(Width, NewWidth, NewHeight, True);

View File

@ -2228,9 +2228,12 @@ function TWinControl.AutoSizeDelayed: boolean;
begin
Result:=// no handle means not visible
(not HandleAllocated)
or ((not FShowing) and (not (csDesigning in ComponentState)))
// during handle creation no autosize
or (wcfCreatingChildHandles in FWinControlFlags)
{$IFNDEF NewAutoSize}
// obsolete
or ((not FShowing) and (not (csDesigning in ComponentState)))
// during handle creation no autosize
or (wcfCreatingChildHandles in FWinControlFlags)
{$ENDIF}
or (inherited AutoSizeDelayed);
//if Result then debugln('TWinControl.AutoSizeDelayed A ',DbgSName(Self),' wcfCreatingChildHandles=',dbgs(wcfCreatingChildHandles in FWinControlFlags),' csLoading=',dbgs(csLoading in ComponentState));
{$IFDEF VerboseCanAutoSize}
@ -2968,7 +2971,9 @@ var
var
i: Integer;
{$IFNDEF NewAutoSize}
ChildControl: TControl;
{$ENDIF}
OldRemainingClientRect: TRect;
OldRemainingBorderSpace: TRect;
MaxTries: LongInt;
@ -2976,6 +2981,9 @@ begin
if wcfAligningControls in FWinControlFlags then exit;
Include(FWinControlFlags,wcfAligningControls);
try
{$IFNDEF NewAutoSize}
// obsolete
// call delayed autosize
for i:=ControlCount-1 downto 0 do begin
ChildControl:=Controls[i];
@ -2984,6 +2992,10 @@ begin
ChildControl.AdjustSize;
end;
end;
{$ENDIF}
{$IFNDEF NewAutoSize}
// obsolete
// unset all align needed flags
Exclude(FWinControlFlags,wcfReAlignNeeded);
@ -2991,6 +3003,7 @@ begin
ChildControl:=Controls[i];
Exclude(ChildControl.FControlFlags,cfRequestAlignNeeded);
end;
{$ENDIF}
//if csDesigning in ComponentState then begin
//DebugLn('[TWinControl.AlignControls] ',Name,':',Classname,' ',Left,',',Top,',',Width,',',Height,' AlignWork=',NeedAlignWork,' ControlCount=',ControlCount);
@ -3046,6 +3059,9 @@ begin
finally
Exclude(FWinControlFlags,wcfAligningControls);
end;
{$IFNDEF NewAutoSize}
// obsolete
// let childs autosize themselves
for i:=0 to ControlCount-1 do begin
ChildControl:=Controls[i];
@ -3054,6 +3070,7 @@ begin
ChildControl.AdjustSize;
end;
end;
{$ENDIF}
end;
function TWinControl.CustomAlignInsertBefore(AControl1, AControl2: TControl): Boolean;
@ -3085,6 +3102,9 @@ begin
ReAlign;
end;
{$IFDEF NewAutoSize}
// deprecated
{$ELSE}
procedure TWinControl.ResizeDelayedAutoSizeChildren;
var
i: Integer;
@ -3122,6 +3142,7 @@ begin
EnableAlign;
end;
end;
{$ENDIF}
procedure TWinControl.InvalidatePreferredChildSizes;
var
@ -3237,7 +3258,10 @@ begin
end;
DisableAutoSizing;
{$IFNDEF NewAutoSize}
// obsolete
DisableAlign;
{$ENDIF}
try
// test if resizing is possible
HasVisibleChilds:=false;
@ -3331,10 +3355,37 @@ begin
finally
Exclude(FControlFlags,cfAutoSizeNeeded);
EnableAutoSizing;
{$IFNDEF NewAutoSize}
// obsolete
EnableAlign;
{$ENDIF}
end;
end;
{$IFDEF NewAutoSize}
procedure TWinControl.DoAllAutoSize;
procedure UpdateShowingRecursive(AWinControl: TWinControl);
var
i: Integer;
begin
if AWinControl.HandleObjectShouldBeVisible
and (not AWinControl.Showing) then
AWinControl.UpdateShowing;
for i:=0 to FWinControls.Count-1 do
UpdateShowingRecursive(TWinControl(AWinControl.FWinControls[i]));
end;
begin
// compute all sizes for LCL objects without touching the widgetset
inherited DoAllAutoSize;
// send all new bounds to widgetset
RealizeBoundsRecursive;
// make handles visible
UpdateShowingRecursive(Self);
end;
{$ENDIF}
{------------------------------------------------------------------------------
TWinControl BroadCast
------------------------------------------------------------------------------}
@ -3406,8 +3457,12 @@ end;
------------------------------------------------------------------------------}
procedure TWinControl.DisableAlign;
begin
{$IFDEF NewAutoSize}
DisableAutoSizing;
{$ELSE}
Inc(FAlignLevel);
//DebugLn(['TWinControl.DisableAlign ',dbgsName(Self),' ',FAlignLevel]);
{$ENDIF}
end;
{-------------------------------------------------------------------------------
@ -3528,6 +3583,9 @@ end;
------------------------------------------------------------------------------}
procedure TWinControl.EnableAlign;
begin
{$IFDEF NewAutoSize}
EnableAutoSizing;
{$ELSE}
Dec(FAlignLevel);
//DebugLn(['TWinControl.EnableAlign ',dbgsName(Self),' ',FAlignLevel]);
if FAlignLevel = 0 then begin
@ -3535,6 +3593,7 @@ begin
or (wcfReAlignNeeded in FWinControlFlags) then
ReAlign;
end;
{$ENDIF}
end;
procedure TWinControl.WriteLayoutDebugReport(const Prefix: string);
@ -3963,15 +4022,36 @@ end;
{------------------------------------------------------------------------------
TWinControl UpdateShowing
Check control's handle visibility.
If handle should become visible the handle and child handles are created.
The
------------------------------------------------------------------------------}
procedure TWinControl.UpdateShowing;
procedure ChangeShowing(bShow: Boolean);
var
ok: Boolean;
begin
if FShowing = bShow then Exit;
FShowing := bShow;
ok := false;
try
Perform(CM_SHOWINGCHANGED, 0, 0); // see TWinControl.CMShowingChanged
ok := true;
finally
if not ok then
FShowing := not bShow;
end;
end;
var
bShow: Boolean;
n: Integer;
ok: boolean;
begin
bShow := HandleObjectShouldBeVisible;
{$IFDEF NewAutoSize}
if bShow then begin
if not HandleAllocated then CreateHandle;
if FWinControls <> nil
@ -3980,23 +4060,34 @@ begin
TWinControl(FWinControls[n]).UpdateShowing;
end;
end;
if not HandleAllocated then Exit;
//DebugLn('TWinControl.UpdateShowing A ',dbgsName(Self),' FShowing=',dbgs(FShowing),' bShow=',dbgs(bShow));
if FShowing = bShow then Exit;
FShowing := bShow;
ok := false;
try
Perform(CM_SHOWINGCHANGED, 0, 0);
ok := true;
finally
if not ok then
FShowing := not bShow;
//DebugLn('TWinControl.UpdateShowing A ',dbgsName(Self),' FShowing=',dbgs(FShowing),' bShow=',dbgs(bShow));
if bShow then
begin
// the Handle should become visible
// delay this until all autosizing has been processed
if AutoSizeDelayed or AutoSizingAll then exit;
end;
ChangeShowing(bShow);
{$ELSE}
if bShow then begin
if not HandleAllocated then CreateHandle;
if FWinControls <> nil
then begin
for n := 0 to FWinControls.Count - 1 do
TWinControl(FWinControls[n]).UpdateShowing;
end;
end;
if not HandleAllocated then Exit;
if FShowing = bShow then Exit;
ChangeShowing(bShow);
//DebugLn(['TWinControl.UpdateShowing ',DbgSName(Self),' FShowing=',FShowing,' AutoSizeDelayed=',AutoSizeDelayed]);
if FShowing then
begin
DisableAlign;
@ -4007,6 +4098,7 @@ begin
EnableAlign;
end;
end;
{$ENDIF}
end;
procedure TWinControl.Update;
@ -5632,6 +5724,13 @@ begin
end;
AControl.FParent := Self;
{$IFDEF NewAutoSize}
if AControl.FAutoSizingLockCount>0 then
begin
// the AControl has disabled autosizing => disable it for the parent=self too
DisableAutoSizing;
end;
{$ENDIF}
end;
{------------------------------------------------------------------------------
@ -5641,6 +5740,9 @@ end;
------------------------------------------------------------------------------}
procedure TWinControl.ReAlign;
begin
{$IFDEF NewAutoSize}
AdjustSize;
{$ELSE}
if (csDestroying in ComponentState) then exit;
if (csLoading in ComponentState) or (not HandleAllocated) then begin
Include(FWinControlFlags,wcfReAlignNeeded);
@ -5655,6 +5757,7 @@ begin
DebugLn('TWinControl.ReAlign B',Name,':',ClassName,' ', Dbgs(BoundsRect));
{$ENDIF}
Exclude(FWinControlFlags,wcfReAlignNeeded);// done
{$ENDIF}
end;
{------------------------------------------------------------------------------
@ -5672,6 +5775,14 @@ begin
end else
ListRemove(FControls, AControl);
AControl.FParent := nil;
{$IFDEF NewAutoSize}
if AControl.FAutoSizingLockCount>0 then
begin
// AControl has disabled autosizing and thus for its parent=Self too
// end disable autosize for parent=self
EnableAutoSizing;
end;
{$ENDIF}
end;
end;
@ -5773,25 +5884,34 @@ end;
procedure TWinControl.InsertControl(AControl: TControl; Index: integer);
begin
AControl.ValidateContainer(Self);
Perform(CM_CONTROLLISTCHANGE, WParam(AControl), LParam(True));
Insert(AControl,Index);
if not (csReading in AControl.ComponentState) then
begin
AControl.Perform(CM_PARENTCOLORCHANGED, 0, 0);
AControl.Perform(CM_PARENTSHOWHINTCHANGED, 0, 0);
AControl.Perform(CM_PARENTBIDIMODECHANGED, 0, 0);
AControl.ParentFontChanged;
if AControl is TWinControl then
TWinControl(AControl).UpdateControlState
else
if HandleAllocated then
AControl.Invalidate;
//DebugLn('TWinControl.InsertControl ',Name,':',ClassName);
{$IFDEF NewAutoSize}
DisableAutoSizing;
try
{$ENDIF}
AControl.ValidateContainer(Self);
Perform(CM_CONTROLLISTCHANGE, WParam(AControl), LParam(True));
Insert(AControl,Index);
if not (csReading in AControl.ComponentState) then
begin
AControl.Perform(CM_PARENTCOLORCHANGED, 0, 0);
AControl.Perform(CM_PARENTSHOWHINTCHANGED, 0, 0);
AControl.Perform(CM_PARENTBIDIMODECHANGED, 0, 0);
AControl.ParentFontChanged;
if AControl is TWinControl then
TWinControl(AControl).UpdateControlState
else
if HandleAllocated then
AControl.Invalidate;
//DebugLn('TWinControl.InsertControl ',Name,':',ClassName);
end;
if not (csDestroying in ComponentState) then
AControl.RequestAlign;
Perform(CM_CONTROLCHANGE, WParam(AControl), LParam(True));
{$IFDEF NewAutoSize}
finally
EnableAutoSizing;
end;
if not (csDestroying in ComponentState) then
AControl.RequestAlign;
Perform(CM_CONTROLCHANGE, WParam(AControl), LParam(True));
{$ENDIF}
//debugln(['TWinControl.InsertControl ',DbgSName(Self),' ',csDesigning in ComponentState,' ',DbgSName(AControl),' ',csDesigning in AControl.ComponentState]);
end;
@ -5802,27 +5922,41 @@ procedure TWinControl.RemoveControl(AControl: TControl);
var
AWinControl: TWinControl;
begin
Perform(CM_CONTROLCHANGE, WParam(AControl), LParam(False));
if AControl is TWinControl then
begin
AWinControl := TWinControl(AControl);
AWinControl.RemoveFocus(True);
if AWinControl.HandleAllocated then
AWinControl.DestroyHandle;
end
else
if HandleAllocated then
AControl.InvalidateControl(AControl.IsVisible, False, True);
Remove(AControl);
if not (csDestroying in ComponentState) then
begin
if AutoSize then
{$IFDEF NewAutoSize}
DisableAutoSizing;
try
{$ENDIF}
Perform(CM_CONTROLCHANGE, WParam(AControl), LParam(False));
if AControl is TWinControl then
begin
AWinControl := TWinControl(AControl);
AWinControl.RemoveFocus(True);
if AWinControl.HandleAllocated then
AWinControl.DestroyHandle;
end
else
if HandleAllocated then
AControl.InvalidateControl(AControl.IsVisible, False, True);
Remove(AControl);
if not (csDestroying in ComponentState) then
begin
{$IFDEF NewAutoSize}
InvalidatePreferredSize;
AdjustSize;
{$ELSE}
if AutoSize then
begin
InvalidatePreferredSize;
AdjustSize;
end;
Realign;
{$ENDIF}
end;
Realign;
{$IFDEF NewAutoSize}
finally
EnableAutoSizing;
end;
{$ENDIF}
end;
{------------------------------------------------------------------------------
@ -5831,9 +5965,11 @@ end;
procedure TWinControl.AlignControl(AControl: TControl);
var
ARect: TRect;
NewRect: TRect;
{$IFNDEF NewAutoSize}
i: Integer;
ChildControl: TControl;
NewRect: TRect;
{$ENDIF}
begin
//if csDesigning in ComponentState then begin
// DbgOut('TWinControl.AlignControl ',Name,':',ClassName);
@ -5841,6 +5977,12 @@ begin
//end;
if csDestroying in ComponentState then exit;
{$IFDEF NewAutoSize}
if AutoSizeDelayed then begin
AdjustSize;
exit;
end;
{$ELSE}
if FAlignLevel <> 0 then begin
Include(FControlState, csAlignmentNeeded);
exit;
@ -5857,7 +5999,18 @@ begin
exit;
end;
end;
{$ENDIF}
{$IFDEF NewAutoSize}
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);
{$ELSE}
DisableAlign;
try
ARect:= GetLogicalClientRect;
@ -5874,6 +6027,7 @@ begin
for i:=0 to FWinControls.Count-1 do
TWinControl(FWinControls[i]).RealizeBoundsRecursive;
end;
{$ENDIF}
end;
{------------------------------------------------------------------------------
@ -6702,7 +6856,10 @@ begin
//RaiseGDBException('');
end;
{$IFNDEF NewAutoSize}
// obsolete
DisableAlign;
{$ENDIF}
DisableAutoSizing;
try
// Control is not visible at this moment. It will be showed in UpdateShowing
@ -6760,11 +6917,19 @@ begin
if FControls<>nil then
for i:=0 to FControls.Count-1 do
TControl(FControls[i]).AdjustSize;
{$IFNDEF NewAutoSize}
// obsolete
// realign childs
ReAlign;
{$ENDIF}
finally
EnableAutoSizing;
{$IFNDEF NewAutoSize}
// obsolete
EnableAlign;
{$ENDIF}
end;
//DebugLn('[TWinControl.CreateWnd] END ',Name,':',Classname);
@ -6791,7 +6956,9 @@ begin
//First set the WinControl property.
//The win32 interface depends on it to determine where to send call backs.
SetProp(Handle,'WinControl',TWinControl(Self));
{$IFNDEF NewAutoSize}
DisableAlign;
{$ENDIF}
DisableAutoSizing;
try
{$IFDEF CHECK_POSITION}
@ -6800,8 +6967,11 @@ begin
' OldRelBounds=',dbgs(FBoundsRealized),
' -> NewBounds=',dbgs(BoundsRect));
{$ENDIF}
{$IFNDEF NewAutoSize}
// obsolete
if (Width>0) and (Height>0) then
DoSendBoundsToInterface;
{$ENDIF}
if wcfColorChanged in FWinControlFlags then
begin
@ -6832,7 +7002,9 @@ begin
else TWSWinControlClass(WidgetSetClass).SetCursor(Self, Screen.Cursors[Cursor]);
finally
EnableAutoSizing;
{$IFNDEF NewAutoSize}
EnableAlign;
{$ENDIF}
end;
// send pending OnResize
Resize;
@ -6920,7 +7092,10 @@ var
LoadedClientSize: TPoint;
CurControl: TWinControl;
begin
{$IFNDEF NewAutoSize}
// obsolete
DisableAlign;
{$ENDIF}
DisableAutoSizing;
try
//DebugLn(['TWinControl.Loaded ',DbgSName(Self),' cfWidthLoaded=',cfWidthLoaded in FControlFlags,' cfHeightLoaded=',cfHeightLoaded in FControlFlags,' ']);
@ -6979,12 +7154,19 @@ begin
inherited Loaded;
FixupTabList;
{$IFNDEF NewAutoSize}
// obsolete
RealizeBounds;
if HandleAllocated and ([csDestroying]*ComponentState=[]) then
DoSendShowHideToInterface;
{$ENDIF}
finally
EnableAutoSizing;
{$IFNDEF NewAutoSize}
// obsolete
EnableAlign;
{$ENDIF}
end;
end;
@ -7105,7 +7287,11 @@ begin
if FRealizeBoundsLockCount<=0 then
RaiseGDBException('UnlockRealizeBounds');
dec(FRealizeBoundsLockCount);
if FRealizeBoundsLockCount=0 then
if (FRealizeBoundsLockCount=0)
{$IFDEF NewAutoSize}
and (not AutoSizingAll) and (not AutoSizeDelayed)
{$ENDIF}
then
RealizeBounds;
end;
@ -7270,7 +7456,11 @@ begin
if [csDesigning,csDestroying,csLoading]*ComponentState=[csDesigning] then
CheckDesignBounds;
// LCL bounds are not up2date -> process new bounds
{$IFDEF NewAutoSize}
DisableAutoSizing;
{$ELSE}
LockRealizeBounds;
{$ENDIF}
try
{$IFDEF CHECK_POSITION}
//if csDesigning in ComponentState then
@ -7283,7 +7473,11 @@ begin
if FUseDockManager and (DockManager <> nil) then
DockManager.ResetBounds(False);
finally
{$IFDEF NewAutoSize}
EnableAutoSizing;
{$ELSE}
UnlockRealizeBounds;
{$ENDIF}
end;
end;
end;
@ -7541,11 +7735,11 @@ procedure TWinControl.RealizeBoundsRecursive;
var
i: Integer;
begin
RealizeBounds;
if FWinControls<>nil then begin
for i:=0 to FWinControls.Count-1 do
TWinControl(FWinControls[i]).RealizeBoundsRecursive;
end;
RealizeBounds;
end;
{------------------------------------------------------------------------------
@ -7554,6 +7748,7 @@ end;
Returns: nothing
Shows or hides a control
Called by UpdateShowing
------------------------------------------------------------------------------}
procedure TWinControl.CMShowingChanged(var Message: TLMessage);
begin