implemented auto sizing: child to parent sizing

git-svn-id: trunk@6206 -
This commit is contained in:
mattias 2004-11-05 22:08:53 +00:00
parent ebaff99d67
commit 5f8024e0d7
6 changed files with 349 additions and 128 deletions

View File

@ -843,8 +843,10 @@ type
protected
// sizing/aligning
AutoSizing: Boolean;
procedure AdjustSize; dynamic;
procedure DoAutoSize; Virtual;
procedure AdjustSize; virtual;
procedure DoAutoSize; virtual;
function AutoSizeCanStart: boolean; virtual;
function AutoSizeDelayed: boolean; virtual;
procedure SetAlign(Value: TAlign); virtual;
procedure SetAnchors(const AValue: TAnchors); virtual;
procedure SetAutoSize(const Value: Boolean); virtual;
@ -963,6 +965,7 @@ type
procedure SetParent(NewParent: TWinControl); virtual;
Procedure SetParentComponent(NewParentComponent: TComponent); override;
procedure WndProc(var TheMessage: TLMessage); virtual;
procedure ParentFormHandleInitialized; virtual; // called by ChildHandlesCreated of parent form
procedure CaptureChanged; virtual;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
Function CanTab: Boolean; virtual;
@ -1056,7 +1059,8 @@ type
procedure SetInitialBounds(aLeft, aTop, aWidth, aHeight: integer); virtual;
procedure SetBoundsKeepBase(aLeft, aTop, aWidth, aHeight: integer;
Lock: boolean); virtual;
procedure GetPreferredSize(var PreferredWidth, PreferredHeight: integer); virtual;
procedure GetPreferredSize(var PreferredWidth, PreferredHeight: integer;
Raw: boolean); virtual;
procedure InvalidatePreferredSize; virtual;
function GetTextBuf(Buffer: PChar; BufSize: Integer): Integer; virtual;
function GetTextLen: Integer; virtual;
@ -1297,7 +1301,9 @@ type
wcfReAlignNeeded,
wcfAligningControls,
wcfEraseBackground,
wcfAutoSizeNeeded
wcfAutoSizeNeeded,
wcfCreatingHandle, // Set while constructing the handle of this control
wcfCreatingChildHandles // Set while constructing the handles of the childs
);
TWinControlFlags = set of TWinControlFlag;
@ -1343,8 +1349,6 @@ type
FTabList: TList;
FUseDockManager: Boolean;
FWinControls: TList;
FCreatingHandle: Boolean; // Set when constructing the handle
// Only used for checking
procedure AlignControl(AControl: TControl);
function GetBrush: TBrush;
function GetControl(const Index: Integer): TControl;
@ -1368,6 +1372,7 @@ type
procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); override;
function GetActionLinkClass: TControlActionLinkClass; override;
procedure AdjustSize; override;
function AutoSizeDelayed: boolean; override;
procedure AdjustClientRect(var ARect: TRect); virtual;
procedure AlignControls(AControl: TControl;
var RemainingClientRect: TRect); virtual;
@ -1388,7 +1393,9 @@ type
procedure DoConstraintsChange(Sender: TObject); override;
procedure DoSetBounds(ALeft, ATop, AWidth, AHeight: integer); override;
procedure DoAutoSize; Override;
procedure CalculatePreferredSize(var PreferredWidth, PreferredHeight: integer); override;
procedure CalculatePreferredSize(var PreferredWidth,
PreferredHeight: integer); override;
procedure GetChildBounds(var ChildBounds: TRect; WithBorderSpace: boolean); virtual;
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
function ChildClassAllowed(ChildClass: TClass): boolean; override;
procedure PaintControls(DC: HDC; First: TControl);
@ -1473,10 +1480,11 @@ type
procedure DoFlipChildren; dynamic;
procedure FixupTabList;
procedure FontChanged(Sender: TObject); override;
procedure InitializeWnd; virtual; //gets called after the window is created
procedure InitializeWnd; virtual; // gets called after the Handle is created and before the child handles are created
procedure Loaded; override;
procedure MainWndProc(var Message: TLMessage);
procedure ParentFormInitializeWnd; virtual; //gets called by InitializeWnd of parent form
procedure MainWndProc(var Msg: TLMessage);
procedure ParentFormHandleInitialized; override;
procedure ChildHandlesCreated; virtual;// called after childs handles are created
procedure ReAlign; // realign all childs
procedure RealSetText(const AValue: TCaption); override;
procedure RemoveFocus(Removing: Boolean);
@ -2488,6 +2496,9 @@ end.
{ =============================================================================
$Log$
Revision 1.256 2004/11/05 22:08:53 mattias
implemented auto sizing: child to parent sizing
Revision 1.255 2004/11/03 14:18:35 mattias
implemented preferred size for controls for theme depending AutoSizing

View File

@ -420,7 +420,7 @@ type
procedure EndFormUpdate;
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
procedure Loaded; override;
procedure InitializeWnd; override;
procedure ChildHandlesCreated; override;
procedure Notification(AComponent: TComponent; Operation : TOperation);override;
procedure PaintWindow(dc : Hdc); override;
procedure RequestAlign; override;

View File

@ -27,14 +27,14 @@
{ $DEFINE CHECK_POSITION}
{------------------------------------------------------------------------------
TControl.AdjustSize
TControl.AdjustSize
Calls DoAutoSize. This method tries to reduce this calls during loading and
handle creation.
------------------------------------------------------------------------------}
procedure TControl.Adjustsize;
begin
if not (csLoading in ComponentState) then begin
SetBoundsKeepBase(Left,Top,Width,Height,Parent<>nil);
end;
if not (csLoading in ComponentState) then DoAutoSize;
end;
{------------------------------------------------------------------------------
@ -350,7 +350,7 @@ begin
try
// resize parents client area
If Parent <> nil then
Parent.DoAutoSize;
Parent.AdjustSize;
if UpdatePosSizeChanged then exit;
// notify before autosizing
BoundsChanged;
@ -1559,6 +1559,16 @@ begin
Dispatch(TheMessage);
end;
{------------------------------------------------------------------------------
procedure TControl.ParentFormHandleInitialized;
called by ChildHandlesCreated of parent form
------------------------------------------------------------------------------}
procedure TControl.ParentFormHandleInitialized;
begin
end;
{------------------------------------------------------------------------------
TControl Invalidate
------------------------------------------------------------------------------}
@ -1567,9 +1577,9 @@ Begin
InvalidateControl(Visible, csOpaque in ControlStyle);
end;
{------------------------------------------------------------------------------}
{ TControl DoMouseDown "Event Handler" }
{------------------------------------------------------------------------------}
{------------------------------------------------------------------------------
TControl DoMouseDown "Event Handler"
------------------------------------------------------------------------------}
procedure TControl.DoMouseDown(var Message: TLMMouse; Button: TMouseButton;
Shift: TShiftState);
begin
@ -1580,9 +1590,9 @@ begin
end;
end;
{------------------------------------------------------------------------------}
{ TControl DoMouseUp "Event Handler" }
{------------------------------------------------------------------------------}
{------------------------------------------------------------------------------
TControl DoMouseUp "Event Handler"
------------------------------------------------------------------------------}
procedure TControl.DoMouseUp(var Message: TLMMouse; Button: TMouseButton);
begin
if not (csNoStdEvents in ControlStyle)
@ -1922,6 +1932,39 @@ Begin
//Handled by TWinControl, or other descendants
end;
{------------------------------------------------------------------------------
function TControl.AutoSizeCanStart: boolean;
Returns true if DoAutoSize can start.
It returns false if
- AutoSize=false
- or the control is currently autosizing
- or the control is not visible
- or the control is destroying
------------------------------------------------------------------------------}
function TControl.AutoSizeCanStart: boolean;
begin
Result:=false;
if not AutoSize then exit;
if AutoSizing then exit;
if (csDestroying in ComponentState) then exit;
if (not (Visible or ((csDesigning in ComponentState)
and (csNoDesignVisible in ControlStyle)))) then exit;
Result:=true;
end;
{------------------------------------------------------------------------------
function TControl.AutoSizeDelayed: boolean;
Returns true, if the DoAutoSize should skip now, because not all parameters
needed to calculate the AutoSize bounds are loaded or initialized.
------------------------------------------------------------------------------}
function TControl.AutoSizeDelayed: boolean;
begin
Result:=(csLoading in ComponentState)
or ((Parent<>nil) and Parent.AutoSizeDelayed);
end;
{------------------------------------------------------------------------------
TControl SetBoundsRect
------------------------------------------------------------------------------}
@ -2215,8 +2258,8 @@ begin
or ([csLoading,csDestroying]*ComponentState<>[])
then exit;
if (CtrlIsVisible or (csDesigning in ComponentState)
and not (csNoDesignVisible in ControlStyle))
if (CtrlIsVisible or ((csDesigning in ComponentState)
and not (csNoDesignVisible in ControlStyle)))
then begin
Rect := BoundsRect;
InvalidateRect(Parent.Handle, @Rect, not (CtrlIsOpaque or
@ -3252,17 +3295,19 @@ end;
{------------------------------------------------------------------------------
procedure TControl.GetPreferredSize(
var PreferredWidth, PreferredHeight: integer);
var PreferredWidth, PreferredHeight: integer; Raw: boolean);
Returns the default/preferred width and height for a control, which is used
by the LCL autosizing algorithms as default size. Only positive values are
valid. Negative or 0 are treated as undefined and the LCL uses other sizes
instead.
If not Raw then then values be be adjusted by the constraints and undefined
values will be replaced by the current width and height.
TWinControl overrides this and asks the interface for theme dependent values.
See TWinControl.GetPreferredSize for more information.
------------------------------------------------------------------------------}
procedure TControl.GetPreferredSize(var PreferredWidth, PreferredHeight: integer
);
procedure TControl.GetPreferredSize(var PreferredWidth,
PreferredHeight: integer; Raw: boolean);
begin
if not (cfPreferredSizeValid in FControlFlags) then begin
CalculatePreferredSize(FPreferredWidth,FPreferredHeight);
@ -3270,6 +3315,32 @@ begin
end;
PreferredWidth:=FPreferredWidth;
PreferredHeight:=FPreferredHeight;
if not Raw then begin
// use Width and Height for undefined preferred size
if PreferredWidth<=0 then PreferredWidth:=Width;
if PreferredHeight<=0 then PreferredHeight:=Height;
// if this control is aligned adjust PreferredWidth and or PreferredHeight
if Parent<>nil then begin
if AnchorAlign[Align]*[akLeft,akRight]=[akLeft,akRight] then begin
// the control will be expanded to maximum width
// -> use the current width, which is or will be eventually set by the
// aligning code
PreferredWidth:=Width;
end;
if AnchorAlign[Align]*[akTop,akBottom]=[akTop,akBottom] then begin
// the control will be expanded to maximum height
// -> use the current height, which is or will be eventually set by the
// aligning code
PreferredHeight:=Height;
end;
end;
// apply constraints
PreferredWidth:=Constraints.MinMaxWidth(PreferredWidth);
PreferredHeight:=Constraints.MinMaxHeight(PreferredHeight);
end;
end;
{------------------------------------------------------------------------------
@ -3348,6 +3419,9 @@ end;
{ =============================================================================
$Log$
Revision 1.221 2004/11/05 22:08:53 mattias
implemented auto sizing: child to parent sizing
Revision 1.220 2004/11/03 14:18:35 mattias
implemented preferred size for controls for theme depending AutoSizing

View File

@ -1553,11 +1553,16 @@ begin
Visible:=true;
end;
procedure TCustomForm.InitializeWnd;
{------------------------------------------------------------------------------
procedure TCustomForm.BeginFormUpdate;
Called after all childs handles are created.
------------------------------------------------------------------------------}
procedure TCustomForm.ChildHandlesCreated;
begin
inherited InitializeWnd;
inherited ChildHandlesCreated;
if Parent<>nil then
ParentFormInitializeWnd;
ParentFormHandleInitialized;
end;
{------------------------------------------------------------------------------
@ -1819,6 +1824,9 @@ end;
{ =============================================================================
$Log$
Revision 1.162 2004/11/05 22:08:53 mattias
implemented auto sizing: child to parent sizing
Revision 1.161 2004/10/25 14:35:13 micha
fix bordericons initialization
fix setting tab page caption (win32)

View File

@ -29,11 +29,32 @@
{------------------------------------------------------------------------------
TWinControl AdjustSize
Calls DoAutoSize smart.
During loading and handle creation the calls are delayed.
This method do the same as TWinControl.DoAutoSize at the beginning.
But since DoAutoSize is commonly overriden by existing Delphi components,
they do not all tests, which can result in too much overhead. To reduce this
the LCL calls AdjustSize instead.
------------------------------------------------------------------------------}
procedure TWinControl.AdjustSize;
begin
inherited AdjustSize;
// Unneeded: RequestAlign;
If not AutoSizeCanStart then exit;
if AutoSizeDelayed then begin
Include(FWinControlFlags,wcfAutoSizeNeeded);
exit;
end;
DoAutoSize;
end;
{------------------------------------------------------------------------------
function TWinControl.AutoSizeDelayed: boolean;
------------------------------------------------------------------------------}
function TWinControl.AutoSizeDelayed: boolean;
begin
Result:=(wcfCreatingChildHandles in FWinControlFlags)
or (inherited AutoSizeDelayed);
end;
{------------------------------------------------------------------------------
@ -571,66 +592,47 @@ end;
Procedure TWinControl.DoAutoSize;
var
I : Integer;
NewBounds : TRect;
NewClientWidth: Integer;
NewClientHeight: Integer;
AControl: TControl;
PreferredWidth: LongInt;
PreferredHeight: LongInt;
ChildBounds: TRect;
begin
//debugln('TWinControl.DoAutoSize ',DbgSName(Self));
If (not AutoSize) or AutoSizing or (csDestroying in ComponentState) then exit;
if csLoading in ComponentState then begin
If not AutoSizeCanStart then exit;
if AutoSizeDelayed then begin
Include(FWinControlFlags,wcfAutoSizeNeeded);
exit;
end;
AutoSizing := True;
try
// autosize control to preferred size
GetPreferredSize(PreferredWidth,PreferredHeight,false);
// move childs tight to left and top
If ControlCount > 0 then begin
// calculate preferred client Size
// TODO: move this to GetPreferredSize
NewBounds := Rect(High(Integer),High(Integer),0,0);
For I := 0 to ControlCount - 1 do begin
AControl:=Controls[I];
If AControl.Visible then begin
With NewBounds do begin
Left := Min(AControl.Left, Left);
Top := Min(AControl.Top, Top);
Right := Max(AControl.Left + AControl.Width, Right);
Bottom := Max(AControl.Top + AControl.Height, Bottom);
end;
end;
end;
For I := 0 to ControlCount - 1 do begin
AControl:=Controls[I];
If AControl <> nil then begin
GetChildBounds(ChildBounds,true);
if (ChildBounds.Left<>0) or (ChildBounds.Top<>0) then begin
For I := 0 to ControlCount - 1 do begin
AControl:=Controls[I];
If AControl.Visible then begin
AControl.Left := AControl.Left - NewBounds.Left;
AControl.Top := AControl.Top - NewBounds.Top;
AControl.SetBoundsKeepBase(AControl.Left - ChildBounds.Left,
AControl.Top - ChildBounds.Top,
AControl.Width,AControl.Height,true);
end;
end;
end;
NewClientWidth := NewBounds.Right - NewBounds.Left;
NewClientHeight := NewBounds.Bottom - NewBounds.Top;
// set new client size
SetClientSize(Point(NewClientWidth, NewClientHeight));
end else begin
// autosize control to preferred size
GetPreferredSize(PreferredWidth,PreferredHeight);
if PreferredWidth<=0 then PreferredWidth:=Width;
if PreferredHeight<=0 then PreferredHeight:=Height;
PreferredWidth:=Constraints.MinMaxWidth(PreferredWidth);
PreferredHeight:=Constraints.MinMaxWidth(PreferredHeight);
//debugln('DoAutoSize A ',DbgSName(Self),' Cur=',dbgs(Width),'x',dbgs(Height),' Prefer=',dbgs(PreferredWidth),'x',dbgs(PreferredHeight),' WidgetClass=',WidgetSetClass.ClassName);
if (PreferredWidth<>Width) or (PreferredHeight<>Height) then begin
//debugln('DoAutoSize Resize ',DbgSName(Self),' W=',dbgs(PreferredWidth),' H=',dbgs(PreferredHeight));
{$IFDEF EnablePreferredSize}
SetBoundsKeepBase(Left,Top,PreferredWidth,PreferredHeight,true);
{$ENDIF}
end;
end;
// set new size
{$IFDEF VerboseAutoSize}
debugln('DoAutoSize A ',DbgSName(Self),' Cur=',dbgs(Width),'x',dbgs(Height),' Prefer=',dbgs(PreferredWidth),'x',dbgs(PreferredHeight),' WidgetClass=',WidgetSetClass.ClassName);
{$ENDIF}
if (PreferredWidth<>Width) or (PreferredHeight<>Height) then begin
//debugln('DoAutoSize Resize ',DbgSName(Self),' W=',dbgs(PreferredWidth),' H=',dbgs(PreferredHeight));
{$IFDEF EnablePreferredSize}
SetBoundsKeepBase(Left,Top,PreferredWidth,PreferredHeight,true);
{$ENDIF}
end;
finally
AutoSizing := False;
@ -1893,8 +1895,6 @@ end;
Procedure TWinControl.WndProc(Var Message: TLMessage);
Var
Form: TCustomForm;
// KeyState: TKeyboardState;
// WheelMsg : TCMMouseWheel;
Begin
// Assert(False, Format('Trace:[TWinControl.WndPRoc] %s(%s) --> Message = %d', [ClassName, Name, Message.Msg]));
case Message.Msg of
@ -2073,15 +2073,14 @@ begin
end;
{------------------------------------------------------------------------------
Method: TWinControl.MainWndProc
Params: Message:
Returns: Nothing
Procedure TWinControl.MainWndProc(Var Message : TLMessage);
Description of the procedure for the class.
The message handler of this wincontrol.
Only needed by controls, which needs features not yet supported by the LCL.
------------------------------------------------------------------------------}
Procedure TWinControl.MainWndProc(Var Message : TLMessage);
Procedure TWinControl.MainWndProc(Var Msg: TLMessage);
Begin
Assert(False, Format('Trace:[TWinControl.MainWndPRoc] %s(%s) --> Message = %d', [ClassName, Name, Message.Msg]));
Assert(False, Format('Trace:[TWinControl.MainWndPRoc] %s(%s) --> Message = %d', [ClassName, Name, Msg.Msg]));
end;
{------------------------------------------------------------------------------
@ -2805,8 +2804,7 @@ end;
------------------------------------------------------------------------------}
constructor TWinControl.Create(TheOwner : TComponent);
begin
FCreatingHandle := False;
// do not set borderstyle, as tcustomform needs to set it before calling
// do not set borderstyle, as tcustomform needs to set it before calling
// inherited, to have it set before handle is created via streaming
// use property that bsNone is zero
//FBorderStyle := bsNone;
@ -3381,7 +3379,7 @@ end;
Params: None
Returns: Nothing
Creates the handle ( = object).
Creates the handle ( = object) if not already done.
------------------------------------------------------------------------------}
procedure TWinControl.CreateHandle;
begin
@ -3412,50 +3410,55 @@ begin
//DebugLn('[TWinControl.CreateWnd] START ',Name,':',Classname);
if (csDestroying in ComponentState) then exit;
if FCreatingHandle
then begin
DebugLn('[WARNING] Recursive call to CreateWnd for ', ClassName, ' (', Name, ')');
if wcfCreatingChildHandles in FWinControlFlags then begin
DebugLn('[WARNING] Recursive call to CreateWnd for ',DbgSName(Self));
Exit;
end;
FCreatingHandle := True;
try
Include(FWinControlFlags,wcfCreatingChildHandles);
Include(FWinControlFlags,wcfCreatingHandle);
try
CreateParams(Params);
with Params do begin
if (WndParent = 0) and (Style and WS_CHILD <> 0) then
RaiseGDBException('TWinControl.CreateWnd: no parent '+Name+':'+ClassName);
Assert((parent <> nil) or (WndParent = 0), 'TODO: find parent if parent=nil and WndParent <> 0');
end;
CreateParams(Params);
with Params do begin
if (WndParent = 0) and (Style and WS_CHILD <> 0) then
RaiseGDBException('TWinControl.CreateWnd: no parent '+Name+':'+ClassName);
Assert((parent <> nil) or (WndParent = 0), 'TODO: find parent if parent=nil and WndParent <> 0');
FHandle := TWSWinControlClass(WidgetSetClass).CreateHandle(Self, Params);
if not HandleAllocated then
RaiseGDBException('Handle creation failed creating '+DbgSName(Self));
Constraints.UpdateInterfaceConstraints;
InvalidatePreferredSize;
FWinControlFlags:=FWinControlFlags-[wcfColorChanged,wcfFontChanged];
finally
Exclude(FWinControlFlags,wcfCreatingHandle);
end;
FHandle := TWSWinControlClass(WidgetSetClass).CreateHandle(Self, Params);
if not HandleAllocated then
RaiseGDBException('Handle creation failed creating '+DbgSName(Self));
Constraints.UpdateInterfaceConstraints;
InvalidatePreferredSize;
FWinControlFlags:=FWinControlFlags-[wcfColorChanged,wcfFontChanged];
//WriteClientRect('A');
if Parent <> nil then AddControl;
//WriteClientRect('B');
InitializeWnd;
//DebugLn('[TWinControl.CreateWnd] ',Name,':',ClassName,' ',Left,',',Top,',',Width,',',Height);
//WriteClientRect('C');
if FWinControls <> nil then begin
for n := 0 to FWinControls.Count - 1 do
with TWinControl(FWinControls.Items[n]) do
if Visible then HandleNeeded;
end;
ChildHandlesCreated;
finally
FCreatingHandle := False;
Exclude(FWinControlFlags,wcfCreatingChildHandles);
end;
//WriteClientRect('A');
if Parent <> nil then AddControl;
//WriteClientRect('B');
InitializeWnd;
//DebugLn('[TWinControl.CreateWnd] ',Name,':',ClassName,' ',Left,',',Top,',',Width,',',Height);
//WriteClientRect('C');
if FWinControls <> nil then begin
for n := 0 to FWinControls.Count - 1 do
with TWinControl(FWinControls.Items[n]) do
if Visible then HandleNeeded;
end;
// size this
// size this control
{$IFDEF EnablePreferredSize}
DoAutoSize;
AdjustSize;
{$ENDIF}
// realign childs
ReAlign;
@ -3538,16 +3541,38 @@ begin
Resize;
end;
procedure TWinControl.ParentFormInitializeWnd;
{------------------------------------------------------------------------------
procedure TWinControl.ParentFormHandleInitialized;
Called after all childs handles of the ParentForm are created.
------------------------------------------------------------------------------}
procedure TWinControl.ParentFormHandleInitialized;
var
i: Integer;
begin
inherited ParentFormHandleInitialized;
if FWinControls <> nil then begin
for i := 0 to FWinControls.Count - 1 do
TWinControl(FWinControls.Items[i]).ParentFormInitializeWnd;
TWinControl(FWinControls.Items[i]).ParentFormHandleInitialized;
end;
if wcfAutoSizeNeeded in FWinControlFlags then AdjustSize;
end;
{------------------------------------------------------------------------------
procedure TWinControl.ChildHandlesCreated;
Called after all childs handles are created.
------------------------------------------------------------------------------}
procedure TWinControl.ChildHandlesCreated;
begin
end;
{------------------------------------------------------------------------------
function TWinControl.ParentHandlesAllocated: boolean;
Checks if all Handles of all Parents are created.
------------------------------------------------------------------------------}
function TWinControl.ParentHandlesAllocated: boolean;
var
CurControl: TWinControl;
@ -3585,7 +3610,7 @@ begin
// autosize this control
if wcfAutoSizeNeeded in FWinControlFlags then
DoAutoSize;
AdjustSize;
RealizeBounds;
// align the childs
@ -3844,16 +3869,93 @@ end;
parent clientrect), then the interface is asked for the preferred size.
For example the preferred size of a TButton is the size, where the label fits
exactly. This depends heavily on the current theme and widgetset.
This value is independent of constraints and siblings, only the inner parts
are relevant.
------------------------------------------------------------------------------}
procedure TWinControl.CalculatePreferredSize(var PreferredWidth,
PreferredHeight: integer);
var
ChildBounds: TRect;
NewClientWidth: Integer;
NewClientHeight: Integer;
OldClientRect: TRect;
begin
inherited CalculatePreferredSize(PreferredWidth, PreferredHeight);
// TODO: calculate childs total preferred size (i.e. move code form DoAutoSize)
//debugln('TWinControl.CalculatePreferredSize ',DbgSName(Self),' HandleAllocated=',dbgs(HandleAllocated));
if HandleAllocated then
TWSWinControlClass(WidgetSetClass).GetPreferredSize(Self,
PreferredWidth, PreferredHeight);
if ControlCount>0 then begin
GetChildBounds(ChildBounds,true);
NewClientWidth := ChildBounds.Right - ChildBounds.Left;
NewClientHeight := ChildBounds.Bottom - ChildBounds.Top;
OldClientRect := GetClientRect;
{$IFDEF VerboseAutoSize}
debugln('TWinControl.CalculatePreferredSize ',DbgSName(Self),
' HandleAllocated=',dbgs(HandleAllocated)+' ChildBounds='+dbgs(ChildBounds),
' Cur='+dbgs(Width)+'x'+dbgs(Height)+
' Client='+dbgs(OldClientRect.Right)+'x'+dbgs(OldClientRect.Bottom));
{$ENDIF}
PreferredWidth:=
Max(PreferredWidth,Width-OldClientRect.Right+NewClientWidth);
PreferredHeight:=
Max(PreferredHeight,Height-OldClientRect.Bottom+NewClientHeight);
end;
{$IFDEF VerboseAutoSize}
debugln('TWinControl.CalculatePreferredSize ',DbgSName(Self),
' HandleAllocated=',dbgs(HandleAllocated),
' Preferred=',dbgs(PreferredWidth),'x',dbgs(PreferredHeight));
{$ENDIF}
end;
{------------------------------------------------------------------------------
procedure TWinControl.GetChildBounds(var ChildBounds: TRect;
WithBorderSpace: boolean);
Calculates the bounds of all visible childs in client coordinates.
------------------------------------------------------------------------------}
procedure TWinControl.GetChildBounds(var ChildBounds: TRect;
WithBorderSpace: boolean);
var
SpaceAround: TRect;
I: Integer;
AControl: TControl;
ChildWidth,ChildHeight: integer;
begin
ChildBounds := Rect(High(Integer),High(Integer),0,0);
SpaceAround:=Rect(0,0,0,0);
For I := 0 to ControlCount - 1 do begin
AControl:=Controls[I];
If AControl.Visible then begin
AControl.GetPreferredSize(ChildWidth,ChildHeight,false);
// TODO: aligned controls
if WithBorderSpace then begin
AControl.BorderSpacing.GetSpaceAround(SpaceAround);
if SpaceAround.Left<ChildSizing.LeftRightSpacing then
SpaceAround.Left:=ChildSizing.LeftRightSpacing;
if SpaceAround.Right<ChildSizing.LeftRightSpacing then
SpaceAround.Right:=ChildSizing.LeftRightSpacing;
if SpaceAround.Top<ChildSizing.TopBottomSpacing then
SpaceAround.Top:=ChildSizing.TopBottomSpacing;
if SpaceAround.Bottom<ChildSizing.TopBottomSpacing then
SpaceAround.Bottom:=ChildSizing.TopBottomSpacing;
end;
With ChildBounds do begin
Left := Min(AControl.Left-SpaceAround.Left, Left);
Top := Min(AControl.Top-SpaceAround.Top, Top);
Right := Max(AControl.Left+ChildWidth+SpaceAround.Right,Right);
Bottom := Max(AControl.Top+ChildHeight+SpaceAround.Bottom,Bottom);
end;
end;
end;
if ChildBounds.Left>ChildBounds.Right then begin
ChildBounds.Left:=0;
ChildBounds.Right:=0;
end;
if ChildBounds.Top>ChildBounds.Bottom then begin
ChildBounds.Top:=0;
ChildBounds.Bottom:=0;
end;
end;
{------------------------------------------------------------------------------
@ -4014,6 +4116,9 @@ end;
{ =============================================================================
$Log$
Revision 1.287 2004/11/05 22:08:53 mattias
implemented auto sizing: child to parent sizing
Revision 1.286 2004/11/03 14:18:36 mattias
implemented preferred size for controls for theme depending AutoSizing

View File

@ -27,13 +27,13 @@ unit GtkWSStdCtrls;
interface
uses
StdCtrls, SysUtils, Controls, Graphics,
Classes, SysUtils, Math, Controls, Graphics, StdCtrls,
{$IFDEF gtk2}
glib2, gdk2pixbuf, gdk2, gtk2, Pango,
{$ELSE}
glib, gdk, gtk, {$Ifndef NoGdkPixbufLib}gdkpixbuf,{$EndIf} GtkFontCache,
{$ENDIF}
WSStdCtrls, WSLCLClasses, GtkInt, Classes, LCLType, GtkDef, LCLProc,
WSStdCtrls, WSLCLClasses, GtkInt, LCLType, GtkDef, LCLProc,
GTKWinApiWindow, gtkglobals, gtkproc, InterfaceBase;
@ -54,6 +54,8 @@ type
private
protected
public
class procedure GetPreferredSize(const AWinControl: TWinControl;
var PreferredWidth, PreferredHeight: integer); override;
end;
{ TGtkWSGroupBox }
@ -958,6 +960,27 @@ begin
//debugln('TGtkWSCustomCheckBox.GetPreferredSize ',DbgSName(AWinControl),' PreferredWidth=',dbgs(PreferredWidth),' PreferredHeight=',dbgs(PreferredHeight));
end;
{ TGtkWSCustomGroupBox }
procedure TGtkWSCustomGroupBox.GetPreferredSize(const AWinControl: TWinControl;
var PreferredWidth, PreferredHeight: integer);
var
Widget: PGtkWidget;
border_width: Integer;
begin
Widget:=PGtkWidget(AWinControl.Handle);
border_width:=(PGtkContainer(Widget)^.flag0 and bm_TGtkContainer_border_width)
shr bp_TGtkContainer_border_width;
PreferredWidth := (border_width + gtk_widget_get_xthickness(Widget)) * 2
+PGtkFrame(Widget)^.label_width;
PreferredHeight := Max(PGtkFrame(Widget)^.label_height,
gtk_widget_get_ythickness(Widget))
+ gtk_widget_get_ythickness(Widget)
+ 2*border_width;
//debugln('TGtkWSCustomGroupBox.GetPreferredSize ',DbgSName(AWinControl),' PreferredWidth=',dbgs(PreferredWidth),' PreferredHeight=',dbgs(PreferredHeight));
end;
initialization
////////////////////////////////////////////////////
@ -967,7 +990,7 @@ initialization
// which actually implement something
////////////////////////////////////////////////////
RegisterWSComponent(TScrollBar, TGtkWSScrollBar);
// RegisterWSComponent(TCustomGroupBox, TGtkWSCustomGroupBox);
RegisterWSComponent(TCustomGroupBox, TGtkWSCustomGroupBox);
// RegisterWSComponent(TGroupBox, TGtkWSGroupBox);
RegisterWSComponent(TCustomComboBox, TGtkWSCustomComboBox);
// RegisterWSComponent(TComboBox, TGtkWSComboBox);