implemented TWinControl.ChildSizing.Layout and ControlsPerLine (still inactive yet). Added an example for it.

git-svn-id: trunk@7959 -
This commit is contained in:
mattias 2005-10-12 10:53:35 +00:00
parent 099bfa8b1e
commit b28e93cbd6
9 changed files with 849 additions and 60 deletions

5
.gitattributes vendored
View File

@ -626,6 +626,11 @@ examples/address_book/mybook.dbf svneol=native#unset
examples/address_book/mybook.mdx svneol=native#unset
examples/address_book/mybook2.dbf svneol=native#unset
examples/address_book/mybook2.mdx svneol=native#unset
examples/autosize/childsizinglayout/childsizinglayout.lpi svneol=native#text/plain
examples/autosize/childsizinglayout/childsizinglayout.lpr svneol=native#text/plain
examples/autosize/childsizinglayout/mainunit.lfm svneol=native#text/plain
examples/autosize/childsizinglayout/mainunit.lrs svneol=native#text/plain
examples/autosize/childsizinglayout/mainunit.pas svneol=native#text/plain
examples/barchart/chartdemo.lpi svneol=native#text/plain
examples/barchart/chartdemo.lpr svneol=native#text/pascal
examples/barchart/frmmain.lfm svneol=native#text/plain

View File

@ -828,7 +828,7 @@ var
CurSide: TAnchorSide;
begin
FAmbiguousBorderSpace:=false;
FBorderSpace:=AControl.BorderSpacing.GetSpace(FAnchorKind);
FBorderSpace:=AControl.BorderSpacing.GetSideSpace(FAnchorKind);
FAmbiguousEnabled:=false;
FEnabled:=(FAnchorKind in AControl.Anchors);
CurSide:=AControl.AnchorSide[FAnchorKind];
@ -843,7 +843,7 @@ var
CurSide: TAnchorSide;
begin
FAmbiguousBorderSpace:=FAmbiguousBorderSpace
or (FBorderSpace<>AControl.BorderSpacing.GetSpace(FAnchorKind));
or (FBorderSpace<>AControl.BorderSpacing.GetSideSpace(FAnchorKind));
FAmbiguousEnabled:=FAmbiguousEnabled
or (FEnabled<>(FAnchorKind in AControl.Anchors));
CurSide:=AControl.AnchorSide[FAnchorKind];

View File

@ -0,0 +1,250 @@
<?xml version="1.0"?>
<CONFIG>
<ProjectOptions>
<PathDelim Value="/"/>
<Version Value="5"/>
<General>
<MainUnit Value="0"/>
<IconPath Value="./"/>
<TargetFileExt Value=""/>
<ActiveEditorIndexAtStart Value="0"/>
</General>
<Units Count="9">
<Unit0>
<Filename Value="childsizinglayout.lpr"/>
<IsPartOfProject Value="True"/>
<UnitName Value="ChildSizingLayout"/>
<UsageCount Value="26"/>
</Unit0>
<Unit1>
<CursorPos X="1" Y="60"/>
<EditorIndex Value="0"/>
<Filename Value="mainunit.pas"/>
<ComponentName Value="ChildsizingLayoutDemoForm"/>
<IsPartOfProject Value="True"/>
<Loaded Value="True"/>
<ResourceFilename Value="mainunit.lrs"/>
<TopLine Value="36"/>
<UnitName Value="MainUnit"/>
<UsageCount Value="26"/>
</Unit1>
<Unit2>
<CursorPos X="10" Y="2692"/>
<EditorIndex Value="2"/>
<Filename Value="/home/mattias/pascal/wichtig/lazarus/lcl/controls.pp"/>
<Loaded Value="True"/>
<TopLine Value="2677"/>
<UnitName Value="Controls"/>
<UsageCount Value="12"/>
</Unit2>
<Unit3>
<CursorPos X="21" Y="3269"/>
<EditorIndex Value="4"/>
<Filename Value="/home/mattias/pascal/wichtig/lazarus/lcl/include/wincontrol.inc"/>
<Loaded Value="True"/>
<TopLine Value="3243"/>
<UsageCount Value="12"/>
</Unit3>
<Unit4>
<CursorPos X="14" Y="167"/>
<EditorIndex Value="1"/>
<Filename Value="/home/mattias/pascal/wichtig/lazarus/lcl/stdctrls.pp"/>
<Loaded Value="True"/>
<TopLine Value="143"/>
<UnitName Value="StdCtrls"/>
<UsageCount Value="12"/>
</Unit4>
<Unit5>
<CursorPos X="2" Y="846"/>
<Filename Value="/home/mattias/pascal/wichtig/lazarus/designer/anchoreditor.pas"/>
<TopLine Value="822"/>
<UnitName Value="AnchorEditor"/>
<UsageCount Value="12"/>
</Unit5>
<Unit6>
<CursorPos X="3" Y="43"/>
<EditorIndex Value="3"/>
<Filename Value="/home/mattias/pascal/wichtig/lazarus/lcl/include/control.inc"/>
<Loaded Value="True"/>
<TopLine Value="30"/>
<UsageCount Value="11"/>
</Unit6>
<Unit7>
<CursorPos X="33" Y="40"/>
<Filename Value="/home/mattias/pascal/wichtig/lazarus/components/rtticontrols/rttigrids.pas"/>
<TopLine Value="16"/>
<UnitName Value="RTTIGrids"/>
<UsageCount Value="10"/>
</Unit7>
<Unit8>
<CursorPos X="22" Y="485"/>
<Filename Value="/home/mattias/pascal/wichtig/lazarus/ideintf/objectinspector.pp"/>
<TopLine Value="451"/>
<UnitName Value="ObjectInspector"/>
<UsageCount Value="10"/>
</Unit8>
</Units>
<PublishOptions>
<Version Value="2"/>
<IgnoreBinaries Value="False"/>
<IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
<ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
</PublishOptions>
<RunParams>
<local>
<FormatVersion Value="1"/>
<LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
</local>
</RunParams>
<RequiredPackages Count="2">
<Item1>
<PackageName Value="RunTimeTypeInfoControls"/>
<MinVersion Minor="1" Valid="True"/>
</Item1>
<Item2>
<PackageName Value="LCL"/>
</Item2>
</RequiredPackages>
<JumpHistory Count="30" HistoryIndex="29">
<Position1>
<Filename Value="mainunit.pas"/>
<Caret Line="60" Column="14" TopLine="35"/>
</Position1>
<Position2>
<Filename Value="mainunit.pas"/>
<Caret Line="35" Column="24" TopLine="35"/>
</Position2>
<Position3>
<Filename Value="mainunit.pas"/>
<Caret Line="41" Column="34" TopLine="35"/>
</Position3>
<Position4>
<Filename Value="mainunit.pas"/>
<Caret Line="40" Column="43" TopLine="35"/>
</Position4>
<Position5>
<Filename Value="mainunit.pas"/>
<Caret Line="60" Column="9" TopLine="29"/>
</Position5>
<Position6>
<Filename Value="mainunit.pas"/>
<Caret Line="41" Column="32" TopLine="17"/>
</Position6>
<Position7>
<Filename Value="mainunit.pas"/>
<Caret Line="46" Column="7" TopLine="17"/>
</Position7>
<Position8>
<Filename Value="mainunit.pas"/>
<Caret Line="40" Column="43" TopLine="17"/>
</Position8>
<Position9>
<Filename Value="mainunit.pas"/>
<Caret Line="36" Column="24" TopLine="17"/>
</Position9>
<Position10>
<Filename Value="mainunit.pas"/>
<Caret Line="48" Column="17" TopLine="33"/>
</Position10>
<Position11>
<Filename Value="mainunit.pas"/>
<Caret Line="80" Column="39" TopLine="36"/>
</Position11>
<Position12>
<Filename Value="/home/mattias/pascal/wichtig/lazarus/lcl/controls.pp"/>
<Caret Line="1306" Column="33" TopLine="1283"/>
</Position12>
<Position13>
<Filename Value="/home/mattias/pascal/wichtig/lazarus/lcl/include/wincontrol.inc"/>
<Caret Line="1052" Column="3" TopLine="1047"/>
</Position13>
<Position14>
<Filename Value="/home/mattias/pascal/wichtig/lazarus/lcl/include/wincontrol.inc"/>
<Caret Line="3119" Column="13" TopLine="3095"/>
</Position14>
<Position15>
<Filename Value="/home/mattias/pascal/wichtig/lazarus/lcl/include/wincontrol.inc"/>
<Caret Line="1" Column="1" TopLine="1"/>
</Position15>
<Position16>
<Filename Value="/home/mattias/pascal/wichtig/lazarus/lcl/include/wincontrol.inc"/>
<Caret Line="3099" Column="13" TopLine="3074"/>
</Position16>
<Position17>
<Filename Value="/home/mattias/pascal/wichtig/lazarus/lcl/include/wincontrol.inc"/>
<Caret Line="3119" Column="13" TopLine="3095"/>
</Position17>
<Position18>
<Filename Value="/home/mattias/pascal/wichtig/lazarus/lcl/include/wincontrol.inc"/>
<Caret Line="3120" Column="36" TopLine="3096"/>
</Position18>
<Position19>
<Filename Value="/home/mattias/pascal/wichtig/lazarus/lcl/include/wincontrol.inc"/>
<Caret Line="3121" Column="15" TopLine="3097"/>
</Position19>
<Position20>
<Filename Value="/home/mattias/pascal/wichtig/lazarus/lcl/include/wincontrol.inc"/>
<Caret Line="3123" Column="67" TopLine="3098"/>
</Position20>
<Position21>
<Filename Value="/home/mattias/pascal/wichtig/lazarus/lcl/include/wincontrol.inc"/>
<Caret Line="3125" Column="68" TopLine="3100"/>
</Position21>
<Position22>
<Filename Value="/home/mattias/pascal/wichtig/lazarus/lcl/include/wincontrol.inc"/>
<Caret Line="3128" Column="58" TopLine="3103"/>
</Position22>
<Position23>
<Filename Value="/home/mattias/pascal/wichtig/lazarus/lcl/include/wincontrol.inc"/>
<Caret Line="3130" Column="61" TopLine="3105"/>
</Position23>
<Position24>
<Filename Value="/home/mattias/pascal/wichtig/lazarus/lcl/include/wincontrol.inc"/>
<Caret Line="3135" Column="32" TopLine="3110"/>
</Position24>
<Position25>
<Filename Value="/home/mattias/pascal/wichtig/lazarus/lcl/include/wincontrol.inc"/>
<Caret Line="3155" Column="32" TopLine="3130"/>
</Position25>
<Position26>
<Filename Value="/home/mattias/pascal/wichtig/lazarus/lcl/include/wincontrol.inc"/>
<Caret Line="3266" Column="32" TopLine="3242"/>
</Position26>
<Position27>
<Filename Value="/home/mattias/pascal/wichtig/lazarus/lcl/include/wincontrol.inc"/>
<Caret Line="1" Column="1" TopLine="1"/>
</Position27>
<Position28>
<Filename Value="/home/mattias/pascal/wichtig/lazarus/lcl/controls.pp"/>
<Caret Line="1295" Column="17" TopLine="1282"/>
</Position28>
<Position29>
<Filename Value="/home/mattias/pascal/wichtig/lazarus/lcl/controls.pp"/>
<Caret Line="2678" Column="48" TopLine="2654"/>
</Position29>
<Position30>
<Filename Value="/home/mattias/pascal/wichtig/lazarus/lcl/controls.pp"/>
<Caret Line="2701" Column="12" TopLine="2677"/>
</Position30>
</JumpHistory>
</ProjectOptions>
<CompilerOptions>
<Version Value="5"/>
<SearchPaths>
<SrcPath Value="$(LazarusDir)/lcl/;$(LazarusDir)/lcl/interfaces/$(LCLWidgetType)/"/>
</SearchPaths>
<CodeGeneration>
<Generate Value="Faster"/>
</CodeGeneration>
<Linking>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
<Other>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
</CONFIG>

View File

@ -0,0 +1,15 @@
program ChildSizingLayout;
{$mode objfpc}{$H+}
uses
Interfaces, // this includes the LCL widgetset
Forms
{ add your units here }, MainUnit, RunTimeTypeInfoControls;
begin
Application.Initialize;
Application.CreateForm(TChildsizingLayoutDemoForm, ChildsizingLayoutDemoForm);
Application.Run;
end.

View File

@ -0,0 +1,111 @@
object ChildsizingLayoutDemoForm: TChildsizingLayoutDemoForm
Caption = 'Childsizing.Layout Demonstration'
ClientHeight = 463
ClientWidth = 728
OnCreate = FormCreate
PixelsPerInch = 112
HorzScrollBar.Page = 727
VertScrollBar.Page = 462
Left = 290
Height = 463
Top = 163
Width = 728
object LayoutLabel: TLabel
AutoSize = False
Caption = 'This is a demonstration of the TWinControl.ChildSizing.Layout property. First change in the radiogroupbox to the right the Layout and watch the LayoutGroupbox. The buttons will automatically align.'
Color = clNone
WordWrap = True
Left = 10
Height = 102
Top = 10
Width = 367
end
object LayoutGroupBox: TGroupBox
Anchors = [akTop, akLeft, akRight, akBottom]
Caption = 'LayoutGroupBox'
ClientHeight = 212
ClientWidth = 376
ParentColor = True
TabOrder = 0
Left = 335
Height = 229
Top = 225
Width = 380
end
object LayoutTIRadioGroup: TTIRadioGroup
BorderSpacing.OnChange = nil
Caption = 'LayoutGroupbox.ChildSizing.Layout'
ParentColor = True
Left = 390
Height = 102
Top = 10
Width = 321
end
object ButtonCountRadioGroup: TRadioGroup
BorderSpacing.OnChange = nil
Caption = 'Number of Buttons'
ColumnLayout = clVerticalThenHorizontal
Columns = 4
Items.Strings = (
'1'
'2'
'3'
'4'
'5'
'7'
'9'
'11'
'13'
'15'
'17'
)
OnClick = ButtonCountRadioGroupClick
ParentColor = True
Left = 20
Height = 110
Top = 130
Width = 260
end
object ControlsPerLineTIRadioGroup: TTIRadioGroup
BorderSpacing.OnChange = nil
Caption = 'LayoutGroupbox.ChildSizing.ControlsPerLine'
Columns = 6
Link.AliasValues.Strings = (
'0=0'
'1=1'
'2=2'
'3=3'
'4=4'
'5=5'
)
ParentColor = True
ParentShowHint = False
ShowHint = True
Left = 290
Height = 55
Hint = 'The LineLength property sets the number of controls per column/row.'
Top = 130
Width = 421
end
object ChildSizingGroupBox: TGroupBox
Anchors = [akTop, akLeft, akBottom]
BorderSpacing.OnChange = nil
Caption = 'LayoutGroupbox.ChildSizing'
ClientHeight = 184
ClientWidth = 256
ParentColor = True
TabOrder = 4
Left = 20
Height = 201
Top = 253
Width = 260
object ChildSizingTIPropertyGrid: TTIPropertyGrid
Align = alClient
BorderSpacing.OnChange = nil
BorderStyle = bsSingle
ValueFont.Color = clMaroon
Height = 184
Width = 256
end
end
end

View File

@ -0,0 +1,38 @@
{ This is an automatically generated lazarus resource file }
LazarusResources.Add('TChildsizingLayoutDemoForm','FORMDATA',[
'TPF0'#26'TChildsizingLayoutDemoForm'#25'ChildsizingLayoutDemoForm'#7'Caption'
+#6' Childsizing.Layout Demonstration'#12'ClientHeight'#3#207#1#11'ClientWidt'
+'h'#3#216#2#8'OnCreate'#7#10'FormCreate'#13'PixelsPerInch'#2'p'#18'HorzScrol'
+'lBar.Page'#3#215#2#18'VertScrollBar.Page'#3#206#1#4'Left'#3'"'#1#6'Height'#3
+#207#1#3'Top'#3#163#0#5'Width'#3#216#2#0#6'TLabel'#11'LayoutLabel'#8'AutoSiz'
+'e'#8#7'Caption'#6#197'This is a demonstration of the TWinControl.ChildSizin'
+'g.Layout property. First change in the radiogroupbox to the right the Layou'
+'t and watch the LayoutGroupbox. The buttons will automatically align.'#5'Co'
+'lor'#7#6'clNone'#8'WordWrap'#9#4'Left'#2#10#6'Height'#2'f'#3'Top'#2#10#5'Wi'
+'dth'#3'o'#1#0#0#9'TGroupBox'#14'LayoutGroupBox'#7'Anchors'#11#5'akTop'#6'ak'
+'Left'#7'akRight'#8'akBottom'#0#7'Caption'#6#14'LayoutGroupBox'#12'ClientHei'
+'ght'#3#212#0#11'ClientWidth'#3'x'#1#11'ParentColor'#9#8'TabOrder'#2#0#4'Lef'
+'t'#3'O'#1#6'Height'#3#229#0#3'Top'#3#225#0#5'Width'#3'|'#1#0#0#13'TTIRadioG'
+'roup'#18'LayoutTIRadioGroup'#22'BorderSpacing.OnChange'#13#7'Caption'#6'!La'
+'youtGroupbox.ChildSizing.Layout'#11'ParentColor'#9#4'Left'#3#134#1#6'Height'
+#2'f'#3'Top'#2#10#5'Width'#3'A'#1#0#0#11'TRadioGroup'#21'ButtonCountRadioGro'
+'up'#22'BorderSpacing.OnChange'#13#7'Caption'#6#17'Number of Buttons'#12'Col'
+'umnLayout'#7#24'clVerticalThenHorizontal'#7'Columns'#2#4#13'Items.Strings'#1
+#6#1'1'#6#1'2'#6#1'3'#6#1'4'#6#1'5'#6#1'7'#6#1'9'#6#2'11'#6#2'13'#6#2'15'#6#2
+'17'#0#7'OnClick'#7#26'ButtonCountRadioGroupClick'#11'ParentColor'#9#4'Left'
+#2#20#6'Height'#2'n'#3'Top'#3#130#0#5'Width'#3#4#1#0#0#13'TTIRadioGroup'#27
+'ControlsPerLineTIRadioGroup'#22'BorderSpacing.OnChange'#13#7'Caption'#6'*La'
+'youtGroupbox.ChildSizing.ControlsPerLine'#7'Columns'#2#6#24'Link.AliasValue'
+'s.Strings'#1#6#3'0=0'#6#3'1=1'#6#3'2=2'#6#3'3=3'#6#3'4=4'#6#3'5=5'#0#11'Par'
+'entColor'#9#14'ParentShowHint'#8#8'ShowHint'#9#4'Left'#3'"'#1#6'Height'#2'7'
+#4'Hint'#6'CThe LineLength property sets the number of controls per column/r'
+'ow.'#3'Top'#3#130#0#5'Width'#3#165#1#0#0#9'TGroupBox'#19'ChildSizingGroupBo'
+'x'#7'Anchors'#11#5'akTop'#6'akLeft'#8'akBottom'#0#22'BorderSpacing.OnChange'
+#13#7'Caption'#6#26'LayoutGroupbox.ChildSizing'#12'ClientHeight'#3#184#0#11
+'ClientWidth'#3#0#1#11'ParentColor'#9#8'TabOrder'#2#4#4'Left'#2#20#6'Height'
+#3#201#0#3'Top'#3#253#0#5'Width'#3#4#1#0#15'TTIPropertyGrid'#25'ChildSizingT'
+'IPropertyGrid'#5'Align'#7#8'alClient'#22'BorderSpacing.OnChange'#13#11'Bord'
+'erStyle'#7#8'bsSingle'#15'ValueFont.Color'#7#8'clMaroon'#6'Height'#3#184#0#5
+'Width'#3#0#1#0#0#0#0
]);

View File

@ -0,0 +1,112 @@
{ Copyright (C) 2005 Mattias Gaertner
This source is free software; you can redistribute it and/or modifyit under
the terms of the GNU General Public License as published bythe Free Software
Foundation; either version 2 of the License, or(at your option) any later
version.
This code is distributed in the hope that it will be useful, butWITHOUT ANY
WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNUGeneral Public License for more details.
A copy of the GNU General Public License is available on the WorldWide Web
at <http://www.gnu.org/copyleft/gpl.html>. You can alsoobtain it by writing
to the Free Software Foundation,Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA.
---------------------------------------------------------------------------
Abstract:
Demonstrates LCL TWinControl.ChildSizing.Layout property.
}
unit MainUnit;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls,
Buttons, RTTICtrls, ExtCtrls, RTTIGrids;
type
{ TChildsizingLayoutDemoForm }
TChildsizingLayoutDemoForm = class(TForm)
ChildSizingGroupBox: TGroupBox;
LayoutGroupBox: TGroupBox;
LayoutLabel: TLabel;
LayoutTIRadioGroup: TTIRadioGroup;
ButtonCountRadioGroup: TRadioGroup;
ControlsPerLineTIRadioGroup: TTIRadioGroup;
ChildSizingTIPropertyGrid: TTIPropertyGrid;
procedure ButtonCountRadioGroupClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
public
procedure SetButtonCount(NewCount: integer);
end;
var
ChildsizingLayoutDemoForm: TChildsizingLayoutDemoForm;
implementation
{ TChildsizingLayoutDemoForm }
procedure TChildsizingLayoutDemoForm.FormCreate(Sender: TObject);
begin
LayoutTIRadioGroup.Link.SetObjectAndProperty(LayoutGroupBox.ChildSizing,'Layout');
ControlsPerLineTIRadioGroup.Link.SetObjectAndProperty(LayoutGroupBox.ChildSizing,'ControlsPerLine');
ChildSizingTIPropertyGrid.TIObject:=LayoutGroupBox.ChildSizing;
SetButtonCount(3);
end;
procedure TChildsizingLayoutDemoForm.SetButtonCount(NewCount: integer);
var
i: Integer;
x: Integer;
begin
if NewCount=LayoutGroupBox.ControlCount then exit;
if ButtonCountRadioGroup.Items.IndexOf(IntToStr(NewCount))<0 then
NewCount:=StrToIntDef(ButtonCountRadioGroup.Items[2],3);
LayoutGroupBox.DisableAlign;
// create buttons
for i:=0 to NewCount-1 do begin
if LayoutGroupBox.ControlCount=i then begin
with TButton.Create(Self) do begin
if LayoutGroupBox.ChildSizing.Layout=cclNone then begin
x:=i*20;
SetBounds(x,x,Width,Height);
end;
Name:='Button'+IntToStr(i);
Parent:=LayoutGroupBox;
end;
end;
// set a caption of various length
LayoutGroupBox.Controls[i].Caption:=
copy(LayoutGroupBox.Controls[i].Name,1,(i mod 5)+3);
end;
// free unneeded buttons
while LayoutGroupBox.ControlCount>NewCount do
LayoutGroupBox.Controls[LayoutGroupBox.ControlCount-1].Free;
LayoutGroupBox.EnableAlign;
// make sure ButtonCountRadioGroup show the correct count
ButtonCountRadioGroup.ItemIndex:=
ButtonCountRadioGroup.Items.IndexOf(IntToStr(NewCount));
end;
procedure TChildsizingLayoutDemoForm.ButtonCountRadioGroupClick(Sender: TObject);
begin
SetButtonCount(StrToIntDef(
ButtonCountRadioGroup.Items[ButtonCountRadioGroup.ItemIndex],3));
end;
initialization
{$I mainunit.lrs}
end.

View File

@ -574,6 +574,7 @@ type
function IsEqual(Spacing: TControlBorderSpacing): boolean;
procedure GetSpaceAround(var SpaceAround: TRect);
function GetSpace(Kind: TAnchorKind): Integer;
function GetSideSpace(Kind: TAnchorKind): Integer;
public
property Control: TControl read FControl;
property Space[Kind: TAnchorKind]: integer read GetSpace write SetSpace;
@ -1071,7 +1072,7 @@ type
procedure SetBoundsKeepBase(aLeft, aTop, aWidth, aHeight: integer;
Lock: boolean = true); virtual;
procedure GetPreferredSize(var PreferredWidth, PreferredHeight: integer;
Raw: boolean); virtual;
Raw: boolean = false); virtual;
procedure CNPreferredSizeChanged;
procedure InvalidatePreferredSize; virtual;
procedure DisableAutoSizing;
@ -1291,18 +1292,18 @@ type
TControlChildSizing = class(TPersistent)
private
FControl: TControl;
FControlsPerLine: integer;
FEnlargeHorizontal: TChildControlEnlargeStyle;
FEnlargeVertical: TChildControlEnlargeStyle;
FHorizontalSpacing: integer;
FLayout: TControlChildrenLayout;
FLeftRightSpacing: integer;
FLines: integer;
FOnChange: TNotifyEvent;
FShrinkHorizontal: TChildControlShrinkStyle;
FShrinkVertical: TChildControlShrinkStyle;
FTopBottomSpacing: integer;
FVerticalSpacing: integer;
procedure SetLines(const AValue: integer);
procedure SetControlsPerLine(const AValue: integer);
procedure SetEnlargeHorizontal(const AValue: TChildControlEnlargeStyle);
procedure SetEnlargeVertical(const AValue: TChildControlEnlargeStyle);
procedure SetHorizontalSpacing(const AValue: integer);
@ -1322,7 +1323,11 @@ type
public
property Control: TControl read FControl;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
// TODO: publish the properties when implemented
published
property LeftRightSpacing: integer read FLeftRightSpacing write SetLeftRightSpacing;
property TopBottomSpacing: integer read FTopBottomSpacing write SetTopBottomSpacing;
property HorizontalSpacing: integer read FHorizontalSpacing write SetHorizontalSpacing;
property VerticalSpacing: integer read FVerticalSpacing write SetVerticalSpacing;
property EnlargeHorizontal: TChildControlEnlargeStyle read FEnlargeHorizontal
write SetEnlargeHorizontal default cesAnchorAligning;
property EnlargeVertical: TChildControlEnlargeStyle read FEnlargeVertical
@ -1332,12 +1337,7 @@ type
property ShrinkVertical: TChildControlShrinkStyle read FShrinkVertical
write SetShrinkVertical default cssAnchorAligning;
property Layout: TControlChildrenLayout read FLayout write SetLayout default cclNone;
property Lines: integer read FLines write SetLines;
published
property LeftRightSpacing: integer read FLeftRightSpacing write SetLeftRightSpacing;
property TopBottomSpacing: integer read FTopBottomSpacing write SetTopBottomSpacing;
property HorizontalSpacing: integer read FHorizontalSpacing write SetHorizontalSpacing;
property VerticalSpacing: integer read FVerticalSpacing write SetVerticalSpacing;
property ControlsPerLine: integer read FControlsPerLine write SetControlsPerLine;
end;
@ -1433,6 +1433,8 @@ type
procedure Insert(AControl: TControl);
procedure Insert(AControl: TControl; Index: integer);
procedure Remove(AControl: TControl);
procedure AlignNonAlignedControls(ListOfControls: TFPList;
var BoundsModified: Boolean);
protected
FWinControlFlags: TWinControlFlags;
procedure AssignTo(Dest: TPersistent); override;
@ -2550,12 +2552,16 @@ end;
function TControlBorderSpacing.GetSpace(Kind: TAnchorKind): Integer;
begin
Result:=Around;
Result:=Around+GetSideSpace(Kind);
end;
function TControlBorderSpacing.GetSideSpace(Kind: TAnchorKind): Integer;
begin
case Kind of
akLeft: inc(Result,Left);
akTop: inc(Result,Top);
akRight: inc(Result,Right);
akBottom: inc(Result,Bottom);
akLeft: Result:=Left;
akTop: Result:=Top;
akRight: Result:=Right;
akBottom: Result:=Bottom;
end;
end;
@ -2575,10 +2581,10 @@ begin
Change;
end;
procedure TControlChildSizing.SetLines(const AValue: integer);
procedure TControlChildSizing.SetControlsPerLine(const AValue: integer);
begin
if FLines=AValue then exit;
FLines:=AValue;
if FControlsPerLine=AValue then exit;
FControlsPerLine:=AValue;
Change;
end;
@ -2601,6 +2607,7 @@ procedure TControlChildSizing.SetLayout(const AValue: TControlChildrenLayout);
begin
if FLayout=AValue then exit;
FLayout:=AValue;
//debugln('TControlChildSizing.SetLayout ',DbgSName(Control));
Change;
end;
@ -2668,6 +2675,8 @@ begin
FEnlargeVertical:=SrcSizing.EnlargeVertical;
FShrinkHorizontal:=SrcSizing.ShrinkHorizontal;
FShrinkVertical:=SrcSizing.ShrinkVertical;
FControlsPerLine:=SrcSizing.ControlsPerLine;
FLayout:=SrcSizing.Layout;
Change;
end else
@ -2688,7 +2697,9 @@ begin
and (FEnlargeHorizontal=Sizing.EnlargeHorizontal)
and (FEnlargeVertical=Sizing.EnlargeVertical)
and (FShrinkHorizontal=Sizing.ShrinkHorizontal)
and (FShrinkVertical=Sizing.ShrinkVertical);
and (FShrinkVertical=Sizing.ShrinkVertical)
and (FControlsPerLine=Sizing.ControlsPerLine)
and (FLayout=Sizing.Layout);
end;
procedure TControlChildSizing.Change;

View File

@ -82,7 +82,6 @@ var
CurControl: TControl;
begin
Result := True;
for I := ControlCount - 1 downto 0 do
begin
CurControl:=Controls[I];
@ -90,6 +89,7 @@ var
or (CurControl.Anchors <> [akLeft, akTop])
or (CurControl.AnchorSide[akLeft].Control<>nil)
or (CurControl.AnchorSide[akTop].Control<>nil)
or (ChildSizing.Layout<>cclNone)
then Exit;
end;
Result := False;
@ -631,36 +631,20 @@ var
procedure DoAlignNotAligned;
// All controls, not aligned by their own properties, can be auto aligned.
{$IFDEF EnableChildSizing}
type
TLine = record
end;
PLine = ^TLine;
var
i: Integer;
Control: TControl;
LineCount: LongInt;
OrthogonalLineCount: Integer;
Lines:
{$ENDIF}
begin
// check if other aligning is enabled
if (ChildSizing.EnlargeHorizontal=cesAnchorAligning)
and (ChildSizing.EnlargeVertical=cesAnchorAligning)
and (ChildSizing.ShrinkHorizontal=cssAnchorAligning)
and (ChildSizing.ShrinkVertical=cssAnchorAligning)
and (ChildSizing.Layout=cclNone)
then
// check if ChildSizing aligning is enabled
if (ChildSizing.Layout=cclNone) then
exit;
{$IFDEF EnableChildSizing}
/// collect all 'not aligned' controls
AlignList.Clear;
for i:=0 to ControlCount-1 do begin
Control := Controls[i];
if (Control.Align=alNone)
and Control.Visible
and (Control.Anchors=[akLeft,akTop])
and (Control.AnchorSide[akLeft].Control=nil)
and (Control.AnchorSide[akTop].Control=nil)
@ -668,14 +652,10 @@ var
AlignList.Add(Control);
end;
end;
//debugln('DoAlignNotAligned ',DbgSName(Self),' AlignList.Count=',dbgs(AlignList.Count));
if AlignList.Count=0 then exit;
// calculate lines of controls, based on preferred sizes
LineCount:=ChildSizing.Lines;
if LineCount>AlignList.Count then LineCount:=AlignList.Count;
OrthogonalLineCount:=((AlignList.Count-1) div LineCount)+1;
GetMem(Lines,LineCount*SizeOf(TLine));
{$ENDIF}
AlignNonAlignedControls(AlignList,BoundsMutated);
end;
var
@ -754,8 +734,9 @@ end;
procedure TWinControl.DoChildSizingChange(Sender: TObject);
begin
//debugln('TWinControl.DoChildSizingChange ',DbgSName(Self));
InvalidatePreferredSize;
AdjustSize;
ReAlign;
end;
procedure TWinControl.ResizeDelayedAutoSizeChildren;
@ -3045,7 +3026,7 @@ end;
{------------------------------------------------------------------------------}
{ TWinControl Remove }
{------------------------------------------------------------------------------}
Procedure TWinControl.Remove(AControl : TControl);
procedure TWinControl.Remove(AControl : TControl);
begin
if AControl <> nil then
begin
@ -3058,13 +3039,279 @@ begin
Listremove(FControls, AControl);
AControl.FParent := Nil;
end;
End;
end;
{------------------------------------------------------------------------------}
{ TWinControl RemoveFocus }
{------------------------------------------------------------------------------}
Procedure TWinControl.RemoveFocus(Removing : Boolean);
//TODO: FINISH TWINCONTROL.REMOVEFOCUS
procedure TWinControl.AlignNonAlignedControls(ListOfControls: TFPList;
var BoundsModified: Boolean);
{ All controls, not aligned by their own properties, can be auto aligned.
Example:
cclLeftToRightThenTopToBottom
+-----------------------------------+ Block
|+---------------------------------+| /
|| Control1 | Control2 | Control 3 ||/
|+---------------------------------+|
|+---------------------------------+|
|| Control4 |Control5| Control 6 |----Box
|+---------------------------------+|
|+---------------------------------+|
|| Control7 | Control8 ||
|+---------------------------------+|
+-----------------------------------+
Block is the outer rectangle and contains an array of TBox.
Each box contains a list of controls.
}
type
PBox = ^TBox;
TBox = record
MinimumSize: TPoint;
MaximumSize: TPoint; // 0 means no maximum
PreferredSize: TPoint;
Border: TRect;
NewSize: TPoint;
ChildCount: Integer;
Childs: PBox;
end;
procedure RaiseConsistencyError;
begin
RaiseGDBException('TWinControl.AlignNonAlignedControls '+DbgSName(Self));
end;
procedure AllocateBoxChilds(Box: PBox; NewChildCount: Integer);
var
Size: Integer;
begin
if NewChildCount=0 then RaiseConsistencyError;
if NewChildCount=Box^.ChildCount then exit;
Size:=NewChildCount*SizeOf(TBox);
GetMem(Box^.Childs,Size);
FillChar(Box^.Childs[0],Size,0);
Box^.ChildCount:=NewChildCount;
end;
var
i: Integer;
Control: TControl;
ControlsPerLine: LongInt; // number of controls per line
LineIndex: LongInt; // index of line
LinePos: LongInt; // position in line
SpaceBetween: LongInt;
Block: TBox;
Line: PBox;
Item: PBox;
LineLeft: LongInt;
LineTop: LongInt;
NewLeft: LongInt;
NewTop: LongInt;
NewWidth: LongInt;
NewHeight: LongInt;
begin
// check if ChildSizing aligning is enabled
if (ChildSizing.Layout=cclNone) or (ListOfControls.Count=0) then
exit;
debugln('TWinControl.AlignNonAlignedControls ',DbgSName(Self),' ListOfControls.Count=',dbgs(ListOfControls.Count));
// allocate Lines
FillChar(Block,SizeOf(Block),0);
ControlsPerLine:=ChildSizing.ControlsPerLine;
if (ControlsPerLine<=0) or (ControlsPerLine>ListOfControls.Count) then
ControlsPerLine:=ListOfControls.Count;
debugln('TWinControl.AlignNonAlignedControls Allocate ControlsPerLine=',dbgs(ControlsPerLine));
// allocate line array for Block
AllocateBoxChilds(@Block,((ListOfControls.Count-1) div ControlsPerLine)+1);
// allocate arrays for the lines
for LineIndex:=0 to Block.ChildCount-2 do
AllocateBoxChilds(@Block.Childs[LineIndex],ControlsPerLine);
AllocateBoxChilds(@Block.Childs[Block.ChildCount-1],
((ListOfControls.Count-1) mod ControlsPerLine)+1);
// collect control bounds
for i:=0 to ListOfControls.Count-1 do begin
Control:=TControl(ListOfControls[i]);
LineIndex:=i div ControlsPerLine;
LinePos:=i mod ControlsPerLine;
debugln('TWinControl.AlignNonAlignedControls collect control bounds ',DbgSName(Control),' LineIndex=',dbgs(LineIndex),' LinePos=',dbgs(LinePos));
if (LineIndex>=Block.ChildCount) then RaiseConsistencyError;
Line:=@(Block.Childs[LineIndex]);
if LinePos>=Line^.ChildCount then RaiseConsistencyError;
Item:=@(Line^.Childs[LinePos]);
Control.BorderSpacing.GetSpaceAround(Item^.Border);
Item^.MinimumSize:=Point(Control.Constraints.EffectiveMinWidth,
Control.Constraints.EffectiveMinHeight);
Item^.MaximumSize:=Point(Control.Constraints.EffectiveMaxWidth,
Control.Constraints.EffectiveMaxHeight);
Control.GetPreferredSize(Item^.PreferredSize.x,Item^.PreferredSize.y,false);
debugln('TWinControl.AlignNonAlignedControls ChildControl=',DbgSName(Control),' Prefer=',dbgs(Item^.PreferredSize),' Min=',dbgs(Item^.MinimumSize),' Max=',dbgs(Item^.MaximumSize),' Border=',dbgs(Item^.Border));
end;
// calculate line bounds
for i:=0 to ListOfControls.Count-1 do begin
Control:=TControl(ListOfControls[i]);
LineIndex:=i div ControlsPerLine;
LinePos:=i mod ControlsPerLine;
Line:=@(Block.Childs[LineIndex]);
Item:=@(Line^.Childs[LinePos]);
if LinePos=0 then begin
Line^.MinimumSize:=Item^.MinimumSize;
Line^.MaximumSize:=Item^.MaximumSize;
Line^.PreferredSize:=Item^.PreferredSize;
Line^.Border:=Item^.Border;
end else begin
// expand line
if ChildSizing.Layout=cclLeftToRightThenTopToBottom then begin
// expand to right of line
SpaceBetween:=Max(Max(Item^.Border.Left,Line^.Border.Right),
ChildSizing.HorizontalSpacing);
inc(Line^.MinimumSize.X,Item^.MinimumSize.X+SpaceBetween);
inc(Line^.MaximumSize.X,Item^.MaximumSize.X+SpaceBetween);
inc(Line^.PreferredSize.X,Item^.PreferredSize.X+SpaceBetween);
Line^.Border.Right:=Control.BorderSpacing.GetSpace(akRight);
end else begin
// add to bottom of line
SpaceBetween:=Max(Max(Item^.Border.Top,Line^.Border.Bottom),
ChildSizing.VerticalSpacing);
inc(Line^.MinimumSize.Y,Item^.MinimumSize.Y+SpaceBetween);
inc(Line^.MaximumSize.Y,Item^.MaximumSize.Y+SpaceBetween);
inc(Line^.PreferredSize.Y,Item^.PreferredSize.Y+SpaceBetween);
Line^.Border.Bottom:=Control.BorderSpacing.GetSpace(akBottom);
end;
end;
debugln('TWinControl.AlignNonAlignedControls LineIndex=',dbgs(LineIndex),' LinePos=',dbgs(LinePos),' Control=',DbgSName(Control),' LinePrefer=',dbgs(Line^.PreferredSize),' LineMin=',dbgs(Line^.MinimumSize),' LineMax=',dbgs(Line^.MaximumSize),' LineBorder=',dbgs(Line^.Border));
end;
// apply ChildSizing border spacings to line bounds
for LineIndex:=0 to Block.ChildCount-1 do begin
Line:=@(Block.Childs[LineIndex]);
if (ChildSizing.Layout=cclLeftToRightThenTopToBottom) then begin
if i=0 then
Line^.Border.Top:=Max(Line^.Border.Top,ChildSizing.TopBottomSpacing)
else
Line^.Border.Top:=Max(Line^.Border.Top,ChildSizing.VerticalSpacing);
if (i=Block.ChildCount-1) then
Line^.Border.Bottom:=Max(Line^.Border.Bottom,ChildSizing.TopBottomSpacing)
else
Line^.Border.Bottom:=Max(Line^.Border.Bottom,ChildSizing.VerticalSpacing);
Line^.Border.Left:=Max(Line^.Border.Left,ChildSizing.HorizontalSpacing);
Line^.Border.Right:=Max(Line^.Border.Right,ChildSizing.HorizontalSpacing);
end else begin
if i=0 then
Line^.Border.Left:=Max(Line^.Border.Left,ChildSizing.LeftRightSpacing)
else
Line^.Border.Left:=Max(Line^.Border.Left,ChildSizing.HorizontalSpacing);
if (i=Block.ChildCount-1) then
Line^.Border.Right:=Max(Line^.Border.Right,ChildSizing.LeftRightSpacing)
else
Line^.Border.Right:=Max(Line^.Border.Right,ChildSizing.HorizontalSpacing);
Line^.Border.Top:=Max(Line^.Border.Top,ChildSizing.VerticalSpacing);
Line^.Border.Bottom:=Max(Line^.Border.Bottom,ChildSizing.VerticalSpacing);
end;
debugln('TWinControl.AlignNonAlignedControls LineIndex=',dbgs(LineIndex),' LinePrefer=',dbgs(Line^.PreferredSize),' LineMin=',dbgs(Line^.MinimumSize),' LineMax=',dbgs(Line^.MaximumSize),' LineBorder=',dbgs(Line^.Border));
end;
// collect block bounds (= total bounds of all lines)
Block.MinimumSize:=Block.Childs[0].MinimumSize;
Block.MaximumSize:=Block.Childs[0].MaximumSize;
Block.PreferredSize:=Block.Childs[0].PreferredSize;
Block.Border:=Block.Childs[0].Border;
debugln('TWinControl.AlignNonAlignedControls BlkPrefer=',dbgs(Block.PreferredSize),' BlkMin=',dbgs(Block.MinimumSize),' BlkMax=',dbgs(Block.MaximumSize),' BlkBorder=',dbgs(Block.Border));
for LineIndex:=1 to Block.ChildCount-1 do begin
Line:=@(Block.Childs[LineIndex]);
if (ChildSizing.Layout=cclLeftToRightThenTopToBottom) then begin
// expand block to bottom
SpaceBetween:=Max(Max(Block.Border.Bottom,Line^.Border.Top),
ChildSizing.VerticalSpacing);
inc(Block.MinimumSize.Y,Line^.MinimumSize.Y+SpaceBetween);
inc(Block.MaximumSize.Y,Line^.MaximumSize.Y+SpaceBetween);
inc(Block.PreferredSize.Y,Line^.PreferredSize.Y+SpaceBetween);
end else begin
// next line is placed at the right side
SpaceBetween:=Max(Max(Block.Border.Right,Line^.Border.Left),
ChildSizing.HorizontalSpacing);
inc(Block.MinimumSize.X,Line^.MinimumSize.X+SpaceBetween);
inc(Block.MaximumSize.X,Line^.MaximumSize.X+SpaceBetween);
inc(Block.PreferredSize.X,Line^.PreferredSize.X+SpaceBetween);
end;
debugln('TWinControl.AlignNonAlignedControls LineIndex=',dbgs(LineIndex),' BlkPrefer=',dbgs(Block.PreferredSize),' BlkMin=',dbgs(Block.MinimumSize),' BlkMax=',dbgs(Block.MaximumSize),' BlkBorder=',dbgs(Block.Border));
end;
// resize total
for LineIndex:=0 to Block.ChildCount-1 do begin
Line:=@(Block.Childs[LineIndex]);
Line^.NewSize:=Line^.PreferredSize;
// TODO
end;
// resize lines
for LineIndex:=0 to Block.ChildCount-1 do begin
Line:=@(Block.Childs[LineIndex]);
for i:=0 to Line^.ChildCount-1 do begin
Item:=@(Line^.Childs[i]);
Item^.NewSize:=Item^.PreferredSize;
// TODO
end;
end;
// apply sizes to controls
LineLeft:=Block.Border.Left;
LineTop:=Block.Border.Top;
NewLeft:=LineLeft;
NewTop:=LineTop;
for i:=0 to ListOfControls.Count-1 do begin
Control:=TControl(ListOfControls[i]);
LineIndex:=i div ControlsPerLine;
LinePos:=i mod ControlsPerLine;
Line:=@(Block.Childs[LineIndex]);
Item:=@(Line^.Childs[LinePos]);
NewWidth:=Item^.NewSize.X;
NewHeight:=Item^.NewSize.Y;
if (Control.Left <> NewLeft) or (Control.Top <> NewTop)
or (Control.Width <> NewWidth) or (Control.Height <> NewHeight) then begin
{ $IFDEF CHECK_POSITION}
//if csDesigning in Control.ComponentState then
//if CompareText(Control.ClassName,CheckPostionClassName)=0 then
with Control do
DebugLn('[TWinControl.AlignNonAlignedControls] NEW BOUNDS Control=',DbgSName(Control),
' New=',dbgs(NewLeft)+','+dbgs(NewTop)+','+dbgs(NewWidth)+'x'+dbgs(NewHeight));
{ $ENDIF}
// lock the base bounds, so that the new automatic bounds do not override
// the user settings
//BoundsModified:=true;
//Control.SetAlignedBounds(NewLeft,NewTop,NewWidth,NewHeight);
end;
if LinePos<Line^.ChildCount-1 then begin
// next control in line
if ChildSizing.Layout=cclLeftToRightThenTopToBottom then
inc(NewLeft,NewWidth+Item^.Border.Right)
else
inc(NewTop,NewHeight+Item^.Border.Bottom);
end else begin
// next line
if ChildSizing.Layout=cclLeftToRightThenTopToBottom then
inc(LineTop,Line^.NewSize.Y+Line^.Border.Bottom)
else
inc(LineLeft,Line^.NewSize.X+Line^.Border.Right);
NewLeft:=LineLeft;
NewTop:=LineTop;
end;
end;
// clean up
for LineIndex:=0 to Block.ChildCount-1 do
FreeMem(Block.Childs[LineIndex].Childs);
FreeMem(Block.Childs);
end;
{------------------------------------------------------------------------------
TWinControl RemoveFocus
------------------------------------------------------------------------------}
procedure TWinControl.RemoveFocus(Removing : Boolean);
var
Form: TCustomForm;
begin
@ -3072,9 +3319,9 @@ begin
if Form <> nil then Form.DefocusControl(Self, Removing);
end;
{------------------------------------------------------------------------------}
{ TWinControl UpdateControlState }
{------------------------------------------------------------------------------}
{------------------------------------------------------------------------------
TWinControl UpdateControlState
------------------------------------------------------------------------------}
procedure TWinControl.UpdateControlState;
var AWinControl: TWinControl;
begin
@ -4347,7 +4594,7 @@ end;
------------------------------------------------------------------------------}
procedure TWinControl.SetChildSizing(const AValue: TControlChildSizing);
begin
if (FChildSizing=AValue) or (FChildSizing.IsEqual(AValue)) then exit;
if (FChildSizing=AValue) then exit;
FChildSizing.Assign(AValue);
end;