286 lines
8.6 KiB
Plaintext
286 lines
8.6 KiB
Plaintext
type t_children_sizer = class()
|
|
{**
|
|
@explan(说明) 子控件布局器 %%
|
|
@param(layout)(bool) 是否布局 %%
|
|
@param(controlsperline)(integer) 每行控件数 %%
|
|
@param(horizontalspacing)(integer) 水平间距 %%
|
|
@param(verticalspacing)(integer) 垂直间距 %%
|
|
@param(leftrightspacing)(integer) 左右间距 %%
|
|
@param(topbottomspacing)(integer) 上下间距 %%
|
|
**}
|
|
//TControlChildrenLayout
|
|
//static const cclNone =0;
|
|
//static const cclLeftToRightThenTopToBottom = 1; // if BiDiMode <> bdLeftToRight then it becomes RightToLeft
|
|
//static const cclTopToBottomThenLeftToRight = 2;
|
|
function create(aowner);
|
|
begin
|
|
fowner := aowner;
|
|
fcontrolsperline := 1;
|
|
flayout := 0;
|
|
fhorizontalspacing := 10;
|
|
fverticalspacing := 10;
|
|
ftopbottomspacing := 10;
|
|
fleftrightspacing := 10;
|
|
fautosizing := 0;
|
|
end
|
|
function AdjustSize(); //调整
|
|
begin
|
|
if flayout=0 then return ;
|
|
if fautosizing then return ;
|
|
if not fowner then return ;
|
|
fautosizing := true;
|
|
faownercls := fowner.ClientRect;
|
|
dolayoutctls(w,h);
|
|
if fowner.autosize then
|
|
begin
|
|
bds := fowner.BoundsRect;
|
|
cls := faownercls;
|
|
dw := (bds[2]-bds[0])-(cls[2]-cls[0]);
|
|
dh := (bds[3]-bds[1])-(cls[3]-cls[1]);
|
|
bds[2] := bds[0]+w+dw;
|
|
bds[3] := bds[1]+h+dh;
|
|
fowner.BoundsRect := bds;
|
|
end
|
|
p := fowner.parent;
|
|
if p and p.autosize then p.AdjustSize();//处理传到
|
|
fautosizing := false;
|
|
end
|
|
function getsizerinfo(); //获取信息
|
|
begin
|
|
r := array();
|
|
r["layout"] := flayout;
|
|
r["controlsperline"] := fcontrolsperline;
|
|
r["horizontalspacing"] := fhorizontalspacing;
|
|
r["verticalspacing"] := fverticalspacing;
|
|
r["topbottomspacing"] := ftopbottomspacing;
|
|
r["leftrightspacing"] := fleftrightspacing;
|
|
return r;
|
|
end
|
|
function setsizerinfo(v);//设置信息
|
|
begin
|
|
if not(ifarray(v) and v) then return ;
|
|
flg := false;
|
|
for i,vi in v do
|
|
begin
|
|
case i of
|
|
"layout" :
|
|
begin
|
|
if vi<>flayout and(vi=0 or vi=1 or vi=2) then
|
|
begin
|
|
flayout := vi;
|
|
if vi then flg := true;
|
|
end
|
|
end
|
|
"controlsperline":
|
|
begin
|
|
if vi<>fcontrolsperline and vi>0 then
|
|
begin
|
|
fcontrolsperline := vi;
|
|
flg := true;
|
|
end
|
|
end
|
|
"horizontalspacing":
|
|
begin
|
|
if vi<>fhorizontalspacing and vi>=0 then
|
|
begin
|
|
fhorizontalspacing := vi;
|
|
flg := true;
|
|
end
|
|
end
|
|
"verticalspacing":
|
|
begin
|
|
if vi<>fverticalspacing and vi>=0 then
|
|
begin
|
|
fverticalspacing := vi;
|
|
flg := true;
|
|
end
|
|
end
|
|
"topbottomspacing":
|
|
begin
|
|
if vi<>ftopbottomspacing and vi>=0 then
|
|
begin
|
|
ftopbottomspacing := vi;
|
|
flg := true;
|
|
end
|
|
end
|
|
"leftrightspacing":
|
|
begin
|
|
if vi<>fleftrightspacing and vi>=0 then
|
|
begin
|
|
fleftrightspacing := vi;
|
|
flg := true;
|
|
end
|
|
end
|
|
end;
|
|
|
|
end
|
|
if flg then
|
|
begin
|
|
AdjustSize();
|
|
end
|
|
end
|
|
property layout read flayout write setlayout;
|
|
property controlsperline read fcontrolsperline write setcontrolsperline;
|
|
property horizontalspacing read fhorizontalspacing write sethorizontalspacing;
|
|
property verticalspacing read fverticalspacing write setverticalspacing;
|
|
property leftrightspacing read fleftrightspacing write setleftrightspacing;
|
|
property topbottomspacing read ftopbottomspacing write settopbottomspacing;
|
|
property autosizing read fautosizing;
|
|
private
|
|
function getwndclass();
|
|
begin
|
|
return class(TWinControl);
|
|
end
|
|
function dolayoutctls(w,h);
|
|
begin
|
|
if not fowner then return ;
|
|
ctls := fowner.Controls;
|
|
r := array();
|
|
ridx := 0;
|
|
cidx := 0;
|
|
ccount := 0;
|
|
for i :=0 to fowner.ControlCount-1 do
|
|
begin
|
|
ctl := ctls[i];
|
|
if not ctl then continue;
|
|
if not ctl.Visible then continue;
|
|
if (ctl is getwndclass()) and ctl.WsPopUp then continue;
|
|
if ctl.ignore_childsizing then continue;
|
|
if cidx>=fcontrolsperline then
|
|
begin
|
|
ccount := fcontrolsperline;
|
|
cidx := 0;
|
|
ridx++;
|
|
end
|
|
wi := 0;hi:=0;
|
|
ctl.GetPreferredSize(wi,hi);
|
|
if flayout=1 then
|
|
r[ridx,cidx] := array(ctl,0,0,wi,hi);
|
|
else r[cidx,ridx] := array(ctl,0,0,wi,hi);
|
|
cidx++;
|
|
end
|
|
ccount := mcols(r);
|
|
ridx := mrows(r);
|
|
//ccount := max(ccount,cidx);
|
|
wsz := zeros(ccount);
|
|
//hsz := zeros(ridx+1);
|
|
hsz := zeros(ridx);
|
|
for i := 0 to length(r)-1 do
|
|
begin
|
|
for j := 0 to length(r[i])-1 do
|
|
//for j := 0 to ccount-1 do
|
|
begin
|
|
hsz[i] := max(hsz[i],r[i,j,4]);
|
|
wsz[j] := max(wsz[j],r[i,j,3]);
|
|
end
|
|
end
|
|
py := ftopbottomspacing+faownercls[1];
|
|
lr := length(r)-1;
|
|
for i := 0 to lr do
|
|
begin
|
|
px := fleftrightspacing+faownercls[0];
|
|
for j := 0 to ccount-1 do
|
|
begin
|
|
vij := r[i,j];
|
|
if not vij then continue;
|
|
vij[1] := px;
|
|
vij[2] := py;
|
|
vij[3] := px+wsz[j];
|
|
vij[4] := py+hsz[i];
|
|
r[i,j] := vij;
|
|
px+=wsz[j];
|
|
if j<ccount-1 then
|
|
px+=fverticalspacing;
|
|
end
|
|
py+=hsz[i];
|
|
if i<lr then py+=horizontalspacing;
|
|
w := max(w,px);
|
|
end
|
|
w +=fleftrightspacing;
|
|
py += ftopbottomspacing;
|
|
h := py;
|
|
for i := 0 to length(r)-1 do
|
|
begin
|
|
for j := 0 to ccount-1 do
|
|
begin
|
|
vi := r[i,j];
|
|
if not vi then continue;
|
|
vi[0].BoundsRect := vi[1:4];
|
|
|
|
end
|
|
end
|
|
w-=faownercls[0];
|
|
h-=faownercls[1];
|
|
return ;
|
|
end
|
|
function setleftrightspacing(v);
|
|
begin
|
|
nv := integer(v);
|
|
if nv<>fleftrightspacing then
|
|
begin
|
|
fleftrightspacing := nv;
|
|
dolayout();
|
|
end
|
|
end
|
|
function settopbottomspacing(v);
|
|
begin
|
|
nv := integer(v);
|
|
if nv<>ftopbottomspacing then
|
|
begin
|
|
ftopbottomspacing := nv;
|
|
dolayout();
|
|
end
|
|
end
|
|
function sethorizontalspacing(v);
|
|
begin
|
|
nv := integer(v);
|
|
if nv<>fhorizontalspacing then
|
|
begin
|
|
fhorizontalspacing := nv;
|
|
dolayout();
|
|
end
|
|
end
|
|
function setverticalspacing(v);
|
|
begin
|
|
nv := integer(v);
|
|
if nv<>fverticalspacing then
|
|
begin
|
|
fverticalspacing := nv;
|
|
dolayout();
|
|
end
|
|
end
|
|
function setlayout(v);
|
|
begin
|
|
if v<>flayout and v in array(0,1,2) then
|
|
begin
|
|
flayout := v;
|
|
if v>0 then
|
|
begin
|
|
dolayout();
|
|
end
|
|
end
|
|
end
|
|
function setcontrolsperline(v);
|
|
begin
|
|
nv := integer(v);
|
|
if nv>0 and fcontrolsperline<>nv then
|
|
begin
|
|
fcontrolsperline := nv;
|
|
dolayout();
|
|
end
|
|
end
|
|
function dolayout();
|
|
begin
|
|
AdjustSize();
|
|
end
|
|
private
|
|
[weakref] fowner;
|
|
fautosizing;
|
|
flayout;
|
|
fcontrolsperline;
|
|
fhorizontalspacing;
|
|
fverticalspacing;
|
|
fleftrightspacing;
|
|
ftopbottomspacing;
|
|
faownercls;
|
|
end |