mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-07 06:16:12 +02:00
LCL:
autosize: turn childs visible before parent autosize without visible handle: clear requests TWinControl.UpdateControlState: call AdjustSize to delay showing after bound computation TWinControl.WMSize: ignore if no bounds were sent to intf TToolBar.CreateWnd: delay autosize TControl.DoAllAutoSize: do not autosize invisible controls git-svn-id: trunk@24377 -
This commit is contained in:
parent
2f70c4458b
commit
e16bb0cfa4
@ -1706,7 +1706,6 @@ type
|
||||
PreferredHeight: integer; WithThemeSpace: Boolean); override;
|
||||
function CheckMenuDropdown(Button: TToolButton): Boolean; virtual;
|
||||
procedure ClickButton(Button: TToolButton); virtual;
|
||||
procedure CreateParams(var Params: TCreateParams); override;
|
||||
procedure CreateWnd; override;
|
||||
procedure ControlsAligned; override;
|
||||
function FindButtonFromAccel(Accel: Word): TToolButton;
|
||||
@ -1716,7 +1715,7 @@ type
|
||||
procedure RepositionButton(Index: Integer);
|
||||
procedure RepositionButtons(Index: Integer);
|
||||
function WrapButtons(UseWidth: integer;
|
||||
var NewWidth, NewHeight: Integer;
|
||||
out NewWidth, NewHeight: Integer;
|
||||
Simulate: boolean): Boolean;
|
||||
public
|
||||
constructor Create(TheOwner: TComponent); override;
|
||||
|
@ -1615,6 +1615,7 @@ type
|
||||
wcfInitializing, // Set while initializing during handle creation
|
||||
wcfCreatingChildHandles, // Set while constructing the handles of the childs
|
||||
wcfRealizingBounds,
|
||||
wcfBoundsRealized, // bounds were sent to the interface
|
||||
wcfUpdateShowing,
|
||||
wcfHandleVisible
|
||||
);
|
||||
@ -2397,6 +2398,8 @@ function DbgS(a: TAnchorKind): string; overload;
|
||||
function DbgS(Anchors: TAnchors): string; overload;
|
||||
function DbgS(a: TAlign): string; overload;
|
||||
function DbgS(a: TAnchorKind; Side: TAnchorSideReference): string; overload;
|
||||
function DbgS(p: TControlAutoSizePhase): string; overload;
|
||||
function DbgS(Phases: TControlAutoSizePhases): string; overload;
|
||||
|
||||
operator := (AVariant: Variant): TCaption;
|
||||
|
||||
@ -2569,6 +2572,25 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function DbgS(p: TControlAutoSizePhase): string; overload;
|
||||
begin
|
||||
Result:=AutoSizePhaseNames[p];
|
||||
end;
|
||||
|
||||
function DbgS(Phases: TControlAutoSizePhases): string; overload;
|
||||
var
|
||||
p: TControlAutoSizePhase;
|
||||
begin
|
||||
Result:='';
|
||||
for p:=Low(TControlAutoSizePhase) to High(TControlAutoSizePhase) do begin
|
||||
if p in Phases then begin
|
||||
if Result<>'' then Result:=Result+',';
|
||||
Result:=Result+AutoSizePhaseNames[p];
|
||||
end;
|
||||
end;
|
||||
Result:='['+Result+']';
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
RecreateWnd
|
||||
This function was originally member of TWincontrol. From a VCL point of view
|
||||
|
@ -2421,6 +2421,8 @@ procedure TControl.DoAllAutoSize;
|
||||
|
||||
//DebugLn(['TControl.DoAllAutoSize.AutoSizeControl ',DbgSName(AControl),' AutoSize=',AControl.AutoSize]);
|
||||
Exclude(AControl.FControlFlags,cfAutoSizeNeeded);
|
||||
if not IsControlVisible then exit;
|
||||
|
||||
if AControl.AutoSize then
|
||||
AControl.DoAutoSize;
|
||||
if AControl is TWinControl then begin
|
||||
|
@ -103,17 +103,20 @@ begin
|
||||
// no flipping
|
||||
end;
|
||||
|
||||
procedure TToolBar.CreateParams(var Params: TCreateParams);
|
||||
begin
|
||||
inherited CreateParams(Params);
|
||||
end;
|
||||
|
||||
procedure TToolBar.CreateWnd;
|
||||
begin
|
||||
BeginUpdate;
|
||||
inherited CreateWnd;
|
||||
UpdateVisibleBar;
|
||||
EndUpdate;
|
||||
try
|
||||
DisableAutoSizing;
|
||||
try
|
||||
inherited CreateWnd;
|
||||
UpdateVisibleBar;
|
||||
finally
|
||||
EnableAutoSizing;
|
||||
end;
|
||||
finally
|
||||
EndUpdate;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TToolBar.ControlsAligned;
|
||||
@ -450,16 +453,17 @@ begin
|
||||
end;
|
||||
|
||||
procedure TToolBar.DoAutoSize;
|
||||
{$IFDEF OldAutoSize}
|
||||
var
|
||||
ModifyWidth, ModifyHeight : Boolean;
|
||||
NewWidth: Integer;
|
||||
NewHeight: Integer;
|
||||
ModifyWidth, ModifyHeight : Boolean;
|
||||
{$ENDIF}
|
||||
begin
|
||||
{$IFDEF OldAutoSize}
|
||||
if AutoSizing then Exit; // we shouldn't come here in the first place
|
||||
BeginAutoSizing;
|
||||
try
|
||||
{$ENDIF}
|
||||
NewWidth:=Width;
|
||||
NewHeight:=Height;
|
||||
GetPreferredSize(NewWidth,NewHeight);
|
||||
@ -472,10 +476,11 @@ begin
|
||||
//DebugLn(['TToolBar.DoAutoSize ',DbgSName(Self),' ',Width,',',Height,' ',NewWidth,',',NewHeight]);
|
||||
if (NewWidth <> Width) or (NewHeight <> Height) then
|
||||
SetBounds(Left, Top, NewWidth, NewHeight);
|
||||
{$IFDEF OldAutoSize}
|
||||
finally
|
||||
EndAutoSizing;
|
||||
end;
|
||||
{$ELSE}
|
||||
// childs are moved in ControlsAligned independent of AutoSize=true
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
@ -535,6 +540,7 @@ begin
|
||||
PreferredHeight := NewHeight;
|
||||
end;
|
||||
{$ENDIF}
|
||||
//DebugLn(['TToolBar.CalculatePreferredSize ',DbgSName(Self),' ',PreferredWidth,'x',PreferredHeight,' Count=',ControlCount]);
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
@ -548,7 +554,7 @@ end;
|
||||
Wrap=true.
|
||||
------------------------------------------------------------------------------}
|
||||
function TToolBar.WrapButtons(UseWidth: integer;
|
||||
var NewWidth, NewHeight: Integer; Simulate: boolean): Boolean;
|
||||
out NewWidth, NewHeight: Integer; Simulate: boolean): Boolean;
|
||||
var
|
||||
ARect: TRect;
|
||||
x: Integer;
|
||||
|
@ -33,7 +33,7 @@
|
||||
{off $DEFINE CHECK_POSITION}
|
||||
{$IFDEF CHECK_POSITION}
|
||||
const CheckPostionClassName = 'xxTPage';
|
||||
const CheckPostionName = 'PropertyStoredIdentPostfixLabel';
|
||||
const CheckPostionName = 'tbViewDebug';
|
||||
const CheckPostionParentName = 'xxxEnvVarsPage';
|
||||
|
||||
function CheckPosition(AControl: TControl): boolean;
|
||||
@ -3440,22 +3440,29 @@ end;
|
||||
{$IFNDEF OldAutoSize}
|
||||
procedure TWinControl.DoAllAutoSize;
|
||||
|
||||
procedure ClearRequests(AControl: TControl);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Exclude(AControl.FControlFlags,cfAutoSizeNeeded);
|
||||
if AControl is TWinControl then
|
||||
for i:=0 to TWinControl(AControl).ControlCount-1 do
|
||||
ClearRequests(TWinControl(AControl).Controls[i]);
|
||||
end;
|
||||
|
||||
procedure UpdateShowingRecursive(AWinControl: TWinControl);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Include(FWinControlFlags,wcfUpdateShowing);
|
||||
try
|
||||
if AWinControl.HandleObjectShouldBeVisible
|
||||
and (not AWinControl.Showing) then
|
||||
AWinControl.UpdateShowing;
|
||||
if AWinControl.FControls<>nil then
|
||||
for i:=0 to AWinControl.FControls.Count-1 do
|
||||
if TObject(AWinControl.FControls[i]) is TWinControl then
|
||||
UpdateShowingRecursive(TWinControl(AWinControl.FControls[i]));
|
||||
finally
|
||||
Exclude(FWinControlFlags,wcfUpdateShowing);
|
||||
end;
|
||||
// first make the childs visible
|
||||
if AWinControl.FControls<>nil then
|
||||
for i:=0 to AWinControl.FControls.Count-1 do
|
||||
if TObject(AWinControl.FControls[i]) is TWinControl then
|
||||
UpdateShowingRecursive(TWinControl(AWinControl.FControls[i]));
|
||||
// then make the control visible
|
||||
if AWinControl.HandleObjectShouldBeVisible
|
||||
and (not AWinControl.Showing) then
|
||||
AWinControl.UpdateShowing;
|
||||
end;
|
||||
|
||||
begin
|
||||
@ -3466,15 +3473,21 @@ begin
|
||||
DebugLn(['TWinControl.DoAllAutoSize START ',DbgSName(Self),' ',dbgs(BoundsRect)]);
|
||||
{$ENDIF}
|
||||
// create needed handles
|
||||
if HandleObjectShouldBeVisible and (not HandleAllocated) then begin
|
||||
{$IFDEF VerboseAllAutoSize}
|
||||
DebugLn(['TWinControl.DoAllAutoSize CREATE HANDLE ',DbgSName(Self)]);
|
||||
{$ENDIF}
|
||||
HandleNeeded;
|
||||
// creating the handle called DisableAutoSizing/EnableAutoSizing
|
||||
// so after handle creation the autosizing was done
|
||||
// => exit
|
||||
exit;
|
||||
if not HandleAllocated then begin
|
||||
if HandleObjectShouldBeVisible then begin
|
||||
{$IFDEF VerboseAllAutoSize}
|
||||
DebugLn(['TWinControl.DoAllAutoSize CREATE HANDLE ',DbgSName(Self)]);
|
||||
{$ENDIF}
|
||||
HandleNeeded;
|
||||
// creating the handle called DisableAutoSizing/EnableAutoSizing
|
||||
// so after handle creation the autosizing was done
|
||||
// => exit
|
||||
exit;
|
||||
end else begin
|
||||
// no autosize possible => remove needed flags
|
||||
ClearRequests(Self);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
Include(FWinControlFlags,wcfAllAutoSizing);
|
||||
@ -3496,7 +3509,12 @@ begin
|
||||
{$IFDEF VerboseAllAutoSize}
|
||||
DebugLn(['TWinControl.DoAllAutoSize UPDATESHOWING ',DbgSName(Self),' lclbounds=',dbgs(BoundsRect)]);
|
||||
{$ENDIF}
|
||||
UpdateShowingRecursive(Self);
|
||||
Include(FWinControlFlags,wcfUpdateShowing);
|
||||
try
|
||||
UpdateShowingRecursive(Self);
|
||||
finally
|
||||
Exclude(FWinControlFlags,wcfUpdateShowing);
|
||||
end;
|
||||
// check if another turn is needed
|
||||
if not (cfAutoSizeNeeded in FControlFlags) then break; // complete
|
||||
end;
|
||||
@ -5981,11 +5999,18 @@ end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
TWinControl UpdateControlState
|
||||
|
||||
Called by: RecreateWnd, TCustomNotebook.ShowCurrentPage,
|
||||
TWinControl.SetParentWindow, TWinControl.InsertControl,
|
||||
TWinControl.CMVisibleChanged
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TWinControl.UpdateControlState;
|
||||
{$IFDEF OldAutoSize}
|
||||
var
|
||||
AWinControl: TWinControl;
|
||||
{$ENDIF}
|
||||
begin
|
||||
{$IFDEF OldAutoSize}
|
||||
AWinControl:= Self;
|
||||
{ If any of the parent is not visible, exit }
|
||||
while AWinControl.Parent <> nil do
|
||||
@ -5997,16 +6022,14 @@ begin
|
||||
if ((AWinControl is TCustomForm) and (AWinControl.Parent=nil))
|
||||
or (AWinControl.FParentWindow <> 0) then
|
||||
begin
|
||||
{$IFDEF OldAutoSize}
|
||||
UpdateShowing;
|
||||
{$ELSE}
|
||||
//DebugLn(['TWinControl.UpdateControlState ',DbgSName(Self),' wcfAllAutoSizing=',wcfAllAutoSizing in FWinControlFlags,' AutoSizeDelayed=',AutoSizeDelayed,' HandleObjectShouldBeVisible=',HandleObjectShouldBeVisible]);
|
||||
if HandleObjectShouldBeVisible then
|
||||
AdjustSize // this will trigger DoAllAutoSize, which calls UpdateShowing
|
||||
else
|
||||
UpdateShowing;
|
||||
{$ENDIF}
|
||||
end;
|
||||
{$ELSE}
|
||||
if HandleObjectShouldBeVisible then
|
||||
AdjustSize // this will trigger DoAllAutoSize, which calls UpdateShowing
|
||||
else
|
||||
UpdateShowing;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
@ -6704,11 +6727,12 @@ begin
|
||||
NewBoundsRealized := Bounds(NewLeft, NewTop, Message.Width, Message.Height);
|
||||
if CompareRect(@NewBoundsRealized, @FBoundsRealized) and
|
||||
(not (wcfClientRectNeedsUpdate in FWinControlFlags)) then exit;
|
||||
FBoundsRealized := NewBoundsRealized;
|
||||
InvalidatePreferredSize;
|
||||
|
||||
{$IFNDEF OldAutoSize}
|
||||
if AutoSizingAll then begin
|
||||
//DebugLn(['TWinControl.WMSize ',DbgSName(Self),' phases=',dbgs(AutoSizePhases)]);
|
||||
if ([caspCreatingHandles,caspComputingBounds]*AutoSizePhases<>[])
|
||||
or (not (wcfBoundsRealized in FWinControlFlags))
|
||||
then begin
|
||||
// while the LCL is creating handles the widgetset may send default bounds
|
||||
// we have not yet told the widgetset the final bounds
|
||||
// => the InvalidatePreferredSize and the InvalidateClientRectCache
|
||||
@ -6716,9 +6740,13 @@ begin
|
||||
// size algorithm to take care of the new bounds
|
||||
// => do not call SetBounds, as this will set the Bounds to the widgetset
|
||||
// default values.
|
||||
//DebugLn(['TWinControl.WMSize from intf ignored, because phases=',dbgs(AutoSizePhases),' boundsrealized=',wcfBoundsRealized in FWinControlFlags]);
|
||||
exit;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
FBoundsRealized := NewBoundsRealized;
|
||||
InvalidatePreferredSize;
|
||||
end;
|
||||
|
||||
{$IFDEF OldAutoSize}
|
||||
@ -7063,6 +7091,9 @@ begin
|
||||
//RaiseGDBException('');
|
||||
end;
|
||||
|
||||
FBoundsRealized:=Rect(0,0,0,0);
|
||||
Exclude(FWinControlFlags,wcfBoundsRealized);
|
||||
|
||||
{$IFDEF OldAutoSize}
|
||||
// obsolete
|
||||
DisableAlign;
|
||||
@ -7094,11 +7125,11 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
//DebugLn(['TWinControl.CreateWnd ',DbgSName(WidgetSetClass),' ',DbgSName(Self)]);
|
||||
//DebugLn(['TWinControl.CreateWnd Creating handle ... ',DbgSName(WidgetSetClass),' ',DbgSName(Self)]);
|
||||
FHandle := TWSWinControlClass(WidgetSetClass).CreateHandle(Self, Params);
|
||||
if not HandleAllocated then
|
||||
RaiseGDBException('Handle creation failed creating '+DbgSName(Self));
|
||||
//debugln('TWinControl.CreateWnd ',DbgSName(Self));
|
||||
//debugln('TWinControl.CreateWnd update constraints ... ',DbgSName(Self));
|
||||
Constraints.UpdateInterfaceConstraints;
|
||||
InvalidateClientRectCache(False);
|
||||
TWSWinControlClass(WidgetSetClass).ConstraintsChange(Self);
|
||||
@ -7112,6 +7143,7 @@ begin
|
||||
//WriteClientRect('B');
|
||||
|
||||
Include(FWinControlFlags, wcfInitializing);
|
||||
//DebugLn(['TWinControl.CreateWnd initializing window ...']);
|
||||
InitializeWnd;
|
||||
|
||||
finally
|
||||
@ -7129,6 +7161,7 @@ begin
|
||||
for i := 0 to FControls.Count - 1 do
|
||||
begin
|
||||
AWinControl := TWinControl(FControls.Items[i]);
|
||||
//DebugLn(['TWinControl.CreateWnd create child handles self=',DbgSName(Self),' Child=',DbgSName(AWinControl)]);
|
||||
if (AWinControl is TWinControl) and AWinControl.IsControlVisible then
|
||||
AWinControl.HandleNeeded;
|
||||
end;
|
||||
@ -7156,7 +7189,7 @@ begin
|
||||
AdjustSize;
|
||||
{$ENDIF}
|
||||
finally
|
||||
//DebugLn(['TWinControl.CreateWnd ',DbgSName(Self)]);
|
||||
//DebugLn(['TWinControl.CreateWnd created ',DbgSName(Self),' enable autosizing ...']);
|
||||
EnableAutoSizing{$IFDEF DebugDisableAutoSizing}('TWinControl.CreateWnd'){$ENDIF};
|
||||
{$IFDEF OldAutoSize}
|
||||
// obsolete
|
||||
@ -7437,6 +7470,7 @@ begin
|
||||
|
||||
TWSWinControlClass(WidgetSetClass).DestroyHandle(Self);
|
||||
Handle := 0;
|
||||
Exclude(FWinControlFlags,wcfBoundsRealized);
|
||||
// Maybe handle is not needed at moment but later it will be created once
|
||||
// again. To propely initialize control after we need to restore color
|
||||
// and font. Request update.
|
||||
@ -7965,10 +7999,29 @@ begin
|
||||
' -> NewBounds=',dbgs(NewBounds));
|
||||
{$ENDIF}
|
||||
FBoundsRealized:=NewBounds;
|
||||
Include(FWinControlFlags,wcfBoundsRealized); // Note: set before calling widgetset, because used in WMSize
|
||||
// this can trigger WMSize messages
|
||||
TWSWinControlClass(WidgetSetClass).SetBounds(Self, Left, Top, Width, Height);
|
||||
end;
|
||||
|
||||
procedure TWinControl.RealizeBounds;
|
||||
|
||||
procedure Check;
|
||||
var
|
||||
c: TWinControl;
|
||||
begin
|
||||
c:=Self;
|
||||
while c<>nil do begin
|
||||
DebugLn(['Check ',DbgSName(c),' ',c.HandleAllocated,
|
||||
' wcfCreatingHandle=',wcfCreatingHandle in FWinControlFlags,
|
||||
' wcfInitializing=',wcfInitializing in FWinControlFlags,
|
||||
' wcfCreatingChildHandles=',wcfCreatingChildHandles in FWinControlFlags,
|
||||
'']);
|
||||
c:=c.Parent;
|
||||
end;
|
||||
RaiseGDBException('');
|
||||
end;
|
||||
|
||||
var
|
||||
NewBounds: TRect;
|
||||
begin
|
||||
@ -7977,8 +8030,10 @@ begin
|
||||
and ([csLoading,csDestroying]*ComponentState=[])
|
||||
and (not (csDestroyingHandle in ControlState))
|
||||
and (not CompareRect(@NewBounds,@FBoundsRealized))
|
||||
and (not IsAParentAligning) then
|
||||
begin
|
||||
{$IFDEF OldAutoSize}
|
||||
and (not IsAParentAligning)
|
||||
{$ENDIF}
|
||||
then begin
|
||||
// the new bounds were not yet sent to the InterfaceObject -> send them
|
||||
{$IFDEF CHECK_POSITION}
|
||||
//if csDesigning in ComponentState then
|
||||
@ -7993,6 +8048,19 @@ begin
|
||||
finally
|
||||
EndUpdateBounds;
|
||||
end;
|
||||
end else begin
|
||||
{$IFDEF CHECK_POSITION}
|
||||
//if CheckPosition(Self) then
|
||||
DbgOut('[TWinControl.RealizeBounds] NOT REALIZING ',DbgSName(Self),
|
||||
' OldRelBounds=',dbgs(FBoundsRealized),
|
||||
' -> NewBounds=',dbgs(NewBounds),
|
||||
', because ');
|
||||
if not HandleAllocated then debugln('not HandleAllocated');
|
||||
if (csLoading in ComponentState) then debugln('csLoading');
|
||||
if (csDestroying in ComponentState) then debugln('csDestroying');
|
||||
if (CompareRect(@NewBounds,@FBoundsRealized)) then debugln('bounds not changed');
|
||||
{$ENDIF}
|
||||
if not HandleAllocated then Check;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -8000,14 +8068,18 @@ procedure TWinControl.RealizeBoundsRecursive;
|
||||
var
|
||||
i: Integer;
|
||||
OldRealizing: boolean;
|
||||
AWinControl: TWinControl;
|
||||
begin
|
||||
if not HandleAllocated then exit;
|
||||
OldRealizing:=wcfRealizingBounds in FWinControlFlags;
|
||||
Include(FWinControlFlags,wcfRealizingBounds);
|
||||
try
|
||||
if FControls<>nil then begin
|
||||
for i:=0 to FControls.Count-1 do
|
||||
if TObject(FControls[i]) is TWinControl then
|
||||
for i:=0 to FControls.Count-1 do begin
|
||||
AWinControl:=TWinControl(FControls[i]);
|
||||
if (AWinControl is TWinControl) then
|
||||
TWinControl(FControls[i]).RealizeBoundsRecursive;
|
||||
end;
|
||||
end;
|
||||
RealizeBounds;
|
||||
finally
|
||||
|
@ -7100,6 +7100,7 @@ begin
|
||||
allocation := PGtkWidget(Window)^.allocation;
|
||||
allocation.width := Width;
|
||||
allocation.height := Height;
|
||||
//DebugLn(['SetWindowSizeAndPosition ',DbgSName(AWinControl),' ',dbgs(allocation)]);
|
||||
gtk_widget_size_allocate(PGtkWidget(Window), @allocation);// Beware: this triggers callbacks
|
||||
|
||||
if (PGtkWidget(Window)^.Window <> nil) then
|
||||
|
Loading…
Reference in New Issue
Block a user