编辑器
修复
This commit is contained in:
@@ -2411,12 +2411,6 @@ type tpagecontrol = class(tcustompagecontrol)
|
||||
inherited;
|
||||
end
|
||||
end
|
||||
type ttabctl = class(t_custom_tab_ctl)
|
||||
function create(AOwner);
|
||||
begin
|
||||
inherited;
|
||||
end
|
||||
end
|
||||
//二分控件
|
||||
type TPairSplitterSide=class(TCustomControl)
|
||||
{**
|
||||
|
||||
@@ -888,7 +888,7 @@ type TCustomMemo = class(TCustomScrollControl,TCustomMemoCmd) //
|
||||
end
|
||||
paintlinestext(RC,FirstLine,LastLine,FirstCol,LastCol);
|
||||
end
|
||||
function DrawLongString(cvs,dtx,tl,r,rnzf);
|
||||
{function DrawLongString2(cvs,dtx,tl,r,rnzf);
|
||||
begin
|
||||
if tl<1 then return ;
|
||||
bt := 0;
|
||||
@@ -912,7 +912,7 @@ type TCustomMemo = class(TCustomScrollControl,TCustomMemoCmd) //
|
||||
lqgqy := 1;
|
||||
while idx<=(nqmzfs) do
|
||||
begin
|
||||
nbt := bytetype(dtx,i)?1:0;
|
||||
nbt := bytetype(dtx,idx)?1:0;
|
||||
if nbt<>bt then
|
||||
begin
|
||||
qgqy[lqgqy++] := array(idx,nbt);
|
||||
@@ -938,13 +938,16 @@ type TCustomMemo = class(TCustomScrollControl,TCustomMemoCmd) //
|
||||
begin
|
||||
ft.charset := 134;
|
||||
end else
|
||||
begin
|
||||
ft.charset := bn;
|
||||
end
|
||||
//echo ">>draw:",dtx2," --- ",ft.charset;
|
||||
cvs.DrawText(dtx2,r2,DT_NOPREFIX);
|
||||
end
|
||||
end
|
||||
ft.charset := bn;
|
||||
end
|
||||
{function DrawLongString2(cvs,dtx,tl,r,rnzf);
|
||||
function DrawLongString(cvs,dtx,tl,r,rnzf);
|
||||
begin
|
||||
bn := 100000;
|
||||
ft := cvs.Font;
|
||||
@@ -987,6 +990,49 @@ type TCustomMemo = class(TCustomScrollControl,TCustomMemoCmd) //
|
||||
ft.charset := bn;
|
||||
end
|
||||
end}
|
||||
function DrawLongString(cvs,dtx,tl,r,rnzf);
|
||||
begin
|
||||
bn := 100000;
|
||||
ft := cvs.Font;
|
||||
if rnzf>tl then
|
||||
begin
|
||||
for i := 1 to tl step 2 do
|
||||
begin
|
||||
if bytetype(dtx,i)<> 0 then
|
||||
begin
|
||||
bn := ft.charset;
|
||||
ft.charset := 134;
|
||||
break;
|
||||
end
|
||||
end
|
||||
cvs.DrawText(dtx,r,DT_NOPREFIX);
|
||||
end else
|
||||
begin
|
||||
qmzfs := max(1,integer((0-r[0])/FCharWidth));
|
||||
if qmzfs>3 and qmzfs<tl then
|
||||
begin
|
||||
if bytetype(dtx,qmzfs)=2 then qmzfs -= 1;
|
||||
end
|
||||
ct := min(tl-qmzfs+1,rnzf);
|
||||
for i := qmzfs to qmzfs+ct step 2 do
|
||||
begin
|
||||
if bytetype(dtx,i)<> 0 then
|
||||
begin
|
||||
bn := ft.charset;
|
||||
ft.charset := 134;
|
||||
break;
|
||||
end
|
||||
end
|
||||
dtx2 := copy(dtx,qmzfs,ct);
|
||||
r[0]+=(qmzfs-1)* FCharWidth;
|
||||
r[2]:= r[0]+ct * FCharWidth;
|
||||
cvs.DrawText(dtx2,r,DT_NOPREFIX);
|
||||
end
|
||||
if bn <> 100000 then
|
||||
begin
|
||||
ft.charset := bn;
|
||||
end
|
||||
end
|
||||
|
||||
function paintlinestext(RC,FirstLine,LastLine,FirstCol,LastCol);virtual;
|
||||
begin
|
||||
|
||||
@@ -1819,7 +1819,8 @@ type TCustomImageList=class(tcomponent)
|
||||
FChanged := true;
|
||||
DestroyHandle();
|
||||
addbmps();
|
||||
if inDesigning()then change();
|
||||
//if inDesigning()then
|
||||
change();
|
||||
end
|
||||
end
|
||||
function SetHeight(h);
|
||||
@@ -1830,7 +1831,8 @@ type TCustomImageList=class(tcomponent)
|
||||
FChanged := true;
|
||||
DestroyHandle();
|
||||
addbmps();
|
||||
if inDesigning()then change();
|
||||
//if inDesigning()then
|
||||
change();
|
||||
//if not inDesigning() then DestroyHandle();
|
||||
end
|
||||
end
|
||||
|
||||
@@ -238,6 +238,27 @@ type TcustomGridCtl = class(tcustomscrollcontrol) //
|
||||
end
|
||||
return r;
|
||||
end
|
||||
function hititemat(xy); //命中
|
||||
begin
|
||||
r := array();
|
||||
if (ifarray(xy) and ifnumber(xy[0]) and ifnumber(xy[1])) then return r;
|
||||
x := xy[0];
|
||||
y := xy[1];
|
||||
ri := GetRowIndexByPos(y);
|
||||
if ri>=0 then
|
||||
begin
|
||||
ci := GetColIndexByPos(x);
|
||||
if ci>=0 then
|
||||
begin
|
||||
r["ridx"]:=ri;
|
||||
r["cidx"]:=ci;
|
||||
rc := GetTureSubItemRect(ri,ci);
|
||||
r["x"]:= x-rc[0];
|
||||
r["y"] := y-rc[1];
|
||||
end
|
||||
end
|
||||
return r;
|
||||
end
|
||||
function InvalidateItem(i);virtual;
|
||||
begin
|
||||
{**
|
||||
|
||||
+166
-603
@@ -1,564 +1,6 @@
|
||||
unit utslvclpage;
|
||||
interface
|
||||
uses utslvclauxiliary,utslvclbase,utslvclgdi;
|
||||
type t_custom_tab_ctl = class(TCustomControl)
|
||||
private
|
||||
fclocker;//锁
|
||||
FirstViewIndex; //第一个展示的序号
|
||||
FCurrentid; //当前
|
||||
FPrevid; //上一个
|
||||
FTabItems; //
|
||||
[weakref]FOnSelChanged;
|
||||
[weakref]FOnSelChanging; //正在改变
|
||||
//FOnrclick;
|
||||
FTabPosition;
|
||||
FTabHeight;
|
||||
FTabItemswidth;
|
||||
FScrollBtnRect;
|
||||
Fprevrect;
|
||||
fnextrect;
|
||||
FTabRects;
|
||||
FClientarea;
|
||||
private
|
||||
function SetTabPosition(v);
|
||||
begin
|
||||
if FTabPosition=v then exit;
|
||||
if not(v in array(alTop,alBottom,alLeft,alRight)) then exit;
|
||||
FTabPosition := v;
|
||||
DoControlAlign();
|
||||
InvalidateRect(nil,false);
|
||||
end
|
||||
function CalcTabs(); //计算区域
|
||||
begin
|
||||
rec := ClientRect; //区域
|
||||
FTabItemswidth := array();
|
||||
for i := 0 to FTabItems.length()-1 do
|
||||
begin
|
||||
wd := FTabItems[i].width;
|
||||
FTabItemswidth[i] := wd;
|
||||
end
|
||||
FMaxsize := 0;
|
||||
if FTabPosition in array(alLeft,alRight) then
|
||||
begin
|
||||
FTabItemswidth := zeros(length(FTabItemswidth))+maxvalue(FTabItemswidth);
|
||||
FMaxsize := length(FTabItemswidth)*FTabHeight;
|
||||
end else
|
||||
begin
|
||||
FMaxsize := sum(FTabItemswidth);
|
||||
end
|
||||
FClientarea := rec;
|
||||
FScrollBtnRect := 0;
|
||||
Fprevrect := 0;
|
||||
fnextrect := 0;
|
||||
FTabRects := array();
|
||||
case FTabPosition of
|
||||
alLeft:
|
||||
begin
|
||||
if FTabItemswidth then
|
||||
begin
|
||||
FClientarea[0] :=rec[0]+FTabItemswidth[0];
|
||||
if length(FTabItemswidth)>1 and (FMaxsize>(rec[3]-rec[1])) then
|
||||
begin
|
||||
FScrollBtnRect := array(rec[0],rec[3]-FTabHeight*2,rec[0]+FTabItemswidth[0],rec[3]);
|
||||
Fprevrect := array(rec[0],rec[3]-FTabHeight*2,rec[0]+FTabItemswidth[0],rec[3]-FTabHeight);
|
||||
Fnextrect := array(rec[0],rec[3]-FTabHeight,rec[0]+FTabItemswidth[0],rec[3]);
|
||||
end else
|
||||
begin
|
||||
FirstViewIndex := 0;
|
||||
end
|
||||
ybase := 0;
|
||||
for i,v in FTabItemswidth do
|
||||
begin
|
||||
if i>=FirstViewIndex then
|
||||
begin
|
||||
FTabRects[i] := array(0,ybase,FTabItemswidth[0],ybase+FTabHeight);
|
||||
ybase+=FTabHeight;
|
||||
if ybase>(rec[3]-FTabHeight-FTabHeight) then break;
|
||||
end
|
||||
else FTabRects[i] := nil;
|
||||
end
|
||||
end
|
||||
end
|
||||
alRight:
|
||||
begin
|
||||
if FTabItemswidth then
|
||||
begin
|
||||
FClientarea[2] :=rec[2]-FTabItemswidth[0];
|
||||
if length(FTabItemswidth)>1 and (FMaxsize>(rec[3]-rec[1])) then
|
||||
begin
|
||||
FScrollBtnRect := array(rec[2]-FTabItemswidth[0],rec[3]-FTabHeight*2,rec[2],rec[3]);
|
||||
Fprevrect := array(rec[2]-FTabItemswidth[0],rec[3]-FTabHeight*2,rec[2],rec[3]-FTabHeight);
|
||||
Fnextrect := array(rec[2]-FTabItemswidth[0],rec[3]-FTabHeight,rec[2],rec[3]);
|
||||
end else
|
||||
FirstViewIndex := 0;
|
||||
ybase := 0;
|
||||
for i,v in FTabItemswidth do
|
||||
begin
|
||||
if i>=FirstViewIndex then
|
||||
begin
|
||||
FTabRects[i] := array(rec[2]-FTabItemswidth[0],ybase,rec[2],ybase+FTabHeight);
|
||||
ybase+=FTabHeight;
|
||||
if ybase>(rec[3]-FTabHeight-FTabHeight) then break;
|
||||
end
|
||||
else FTabRects[i] := nil;
|
||||
end
|
||||
end
|
||||
end
|
||||
alTop:
|
||||
begin
|
||||
if FTabItemswidth then
|
||||
begin
|
||||
FClientarea[1] :=rec[1]+FTabHeight;
|
||||
if length(FTabItemswidth)>1 and (FMaxsize>(rec[2]-rec[0])) then
|
||||
begin
|
||||
FScrollBtnRect := array(rec[2]-FTabHeight*2,rec[1],rec[2],rec[1]+FTabHeight);
|
||||
|
||||
Fnextrect := array(rec[2]-FTabHeight,rec[1],rec[2],rec[1]+FTabHeight);
|
||||
Fprevrect := array(rec[2]-FTabHeight*2,rec[1],rec[2]-FTabHeight,rec[1]+FTabHeight);
|
||||
end else FirstViewIndex := 0;
|
||||
xbase := 0;
|
||||
for i,v in FTabItemswidth do
|
||||
begin
|
||||
if i>=FirstViewIndex then
|
||||
begin
|
||||
FTabRects[i] := array(xbase,0,xbase+FTabItemswidth[i],FTabHeight);
|
||||
xbase+=FTabItemswidth[i];
|
||||
if xbase>(rec[2]-FTabHeight-FTabHeight) then break;
|
||||
end else
|
||||
FTabRects[i] := nil;
|
||||
end
|
||||
end
|
||||
end
|
||||
alBottom:
|
||||
begin
|
||||
if FTabItemswidth then
|
||||
begin
|
||||
FClientarea[3] :=rec[3]-FTabHeight;
|
||||
if length(FTabItemswidth)>1 and (FMaxsize>(rec[2]-rec[0])) then
|
||||
begin
|
||||
FScrollBtnRect := array(rec[2]-FTabHeight*2,rec[3]-FTabHeight,rec[2],rec[3]);
|
||||
Fnextrect := array(rec[2]-FTabHeight,rec[3]-FTabHeight,rec[2],rec[3]);
|
||||
Fprevrect := array(rec[2]-FTabHeight*2,rec[3]-FTabHeight,rec[2]-FTabHeight,rec[3]);
|
||||
end else FirstViewIndex := 0;
|
||||
xbase := 0;
|
||||
for i,v in FTabItemswidth do
|
||||
begin
|
||||
if i>=FirstViewIndex then
|
||||
begin
|
||||
FTabRects[i] := array(xbase,rec[3]-FTabHeight,xbase+FTabItemswidth[i],rec[3]);
|
||||
xbase+=FTabItemswidth[i];
|
||||
if xbase>(rec[2]-FTabHeight-FTabHeight) then break;
|
||||
end else
|
||||
FTabRects[i] := nil;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
function InsureIdxVisible(id); //确保可见
|
||||
begin
|
||||
if not(id>=0 and id<FTabItems.length()) then return 0;
|
||||
while FScrollBtnRect and (not FTabRects[id]) do
|
||||
begin
|
||||
if id>FirstViewIndex then
|
||||
begin
|
||||
FirstViewIndex++;
|
||||
end else
|
||||
begin
|
||||
FirstViewIndex--;
|
||||
end
|
||||
CalcTabs();
|
||||
end
|
||||
end
|
||||
function setselidx(id); //选择序号
|
||||
begin
|
||||
if FCurrentid= id then return ;
|
||||
if fclocker.locked then return ;
|
||||
lk := new tcountlocker(fclocker);
|
||||
if id>=0 and id<FTabItems.length() then
|
||||
begin
|
||||
if FCurrentid<>-1 and fOnSelChanging then
|
||||
begin
|
||||
e := new tuieventbase(0,FCurrentid,id,0); //m,w,l,h
|
||||
doonSelChanging(self(true),e);
|
||||
if e.skip then return ;
|
||||
end
|
||||
FPrevid := FCurrentid;
|
||||
FCurrentid := id;
|
||||
InsureIdxVisible(id);
|
||||
InvalidateRect(nil,false);
|
||||
if FOnSelChanged then
|
||||
begin
|
||||
doonSelChange(self(true),new tuieventbase(0,FPrevid,FCurrentid,0));
|
||||
end
|
||||
end else
|
||||
if FTabItems.length()=0 then
|
||||
begin
|
||||
FPrevid := -1;
|
||||
FCurrentid := -1;
|
||||
end
|
||||
end
|
||||
function PaintTabs();//绘制tab
|
||||
begin
|
||||
lk := new tcountlocker(fclocker);
|
||||
dc := Canvas;
|
||||
dc.font := font;
|
||||
ar := 0->(FTabItems.length()-1);
|
||||
if FTabRects[FCurrentid] then
|
||||
begin
|
||||
ar[FCurrentid] := -100;
|
||||
ar[length(ar)] := FCurrentid;
|
||||
end
|
||||
for ii,i in ar do
|
||||
begin
|
||||
rec := FTabRects[i];
|
||||
if rec then
|
||||
begin
|
||||
if fownerdraw and fondrawtab then
|
||||
begin
|
||||
e := new teventdrawtab(i,(FCurrentid=i),rec,dc);
|
||||
CallMessgeFunction(fondrawtab,self(true),e);
|
||||
continue;
|
||||
end
|
||||
dc.pen.color := 13158600;//rgb(200,200,200);
|
||||
if FCurrentid=i then
|
||||
begin
|
||||
dc.brush.color := 0xf0f0f0;//rgb(100,192,250);//rgb(230,240,250);//rgb(200,200,200);
|
||||
end else dc.brush.color := 16711422;//rgb(254,254,254);
|
||||
dc.draw("roundrect",array(rec[0:1],rec[2:3],array(2,2)));
|
||||
rec[1]+=2;
|
||||
it := FTabItems[i];
|
||||
dc.drawtext(it.caption,rec,DT_CENTER .|DT_VCENTER);
|
||||
end
|
||||
end
|
||||
end
|
||||
function PaintScroll(); //绘制滚动
|
||||
begin
|
||||
dc := Canvas;
|
||||
if FScrollBtnRect then
|
||||
begin
|
||||
case FTabPosition of
|
||||
alTop,alBottom:
|
||||
begin
|
||||
rc1 := array(FScrollBtnRect[0:1]+1,(FScrollBtnRect[0]+FTabHeight-1,FScrollBtnRect[3]-1));
|
||||
dc.draw("framecontrol",rc1,DFC_SCROLL,DFCS_SCROLLLEFT);
|
||||
rc1 := array((FScrollBtnRect[0]+FTabHeight+1,FScrollBtnRect[1]+1),FScrollBtnRect[2:3]-1);
|
||||
dc.draw("framecontrol",rc1,DFC_SCROLL,DFCS_SCROLLRIGHT);
|
||||
end else
|
||||
begin
|
||||
rc1 := array(FScrollBtnRect[0:1]+1,(FScrollBtnRect[2]-1,FScrollBtnRect[3]-FTabHeight-1));
|
||||
dc.draw("framecontrol",rc1,DFC_SCROLL,DFCS_SCROLLUP);
|
||||
rc1 := array((FScrollBtnRect[0]+1,FScrollBtnRect[3]-FTabHeight+1),FScrollBtnRect[2:3]-1);
|
||||
dc.draw("framecontrol",rc1,DFC_SCROLL,DFCS_SCROLLDOWN);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
function ScrollPrev(); //滚动到下一个
|
||||
begin
|
||||
if FScrollBtnRect and FirstViewIndex>0 then
|
||||
begin
|
||||
FirstViewIndex-- ;
|
||||
CalcTabs();
|
||||
InvalidateRect(nil,false);
|
||||
end
|
||||
end
|
||||
function scrollnext(); //滚动到上一个
|
||||
begin
|
||||
if FScrollBtnRect and FirstViewIndex<FTabItems.length() then
|
||||
begin
|
||||
rec := FTabRects[FTabItems.length()-1];
|
||||
case FTabPosition of
|
||||
alTop,alBottom:
|
||||
begin
|
||||
if rec and (rec[2]<Fprevrect[0]) then return ;
|
||||
end
|
||||
alLeft,alRight :
|
||||
begin
|
||||
if rec and (rec[3]<Fprevrect[1]) then return ;
|
||||
end
|
||||
end ;
|
||||
FirstViewIndex++ ;
|
||||
CalcTabs();
|
||||
InvalidateRect(nil,false);
|
||||
end
|
||||
end
|
||||
public
|
||||
function HitTesttabat(xy);
|
||||
begin
|
||||
r := array();
|
||||
{if pointinrect(xy,fnextrect) then
|
||||
begin
|
||||
r["idx"] :=-1;
|
||||
return r;
|
||||
end
|
||||
if pointinrect(xy,Fprevrect) then
|
||||
begin
|
||||
r["idx"] := -2;
|
||||
end }
|
||||
for i,v in FTabRects do
|
||||
begin
|
||||
if v and pointinrect(xy,v) then
|
||||
begin
|
||||
r["idx"] := i;
|
||||
r["pos"] := array(xy[0]-v[0],xy[1]-v[1]);
|
||||
return r;
|
||||
end
|
||||
end
|
||||
return r;
|
||||
end
|
||||
function inserttab(tbs,idx);virtual;
|
||||
begin
|
||||
nitem := array();
|
||||
ti := 0;
|
||||
ftw := font.width;
|
||||
for i,v in tbs do
|
||||
begin
|
||||
if not ifstring(v) then return 0;
|
||||
it := new t_tab_item(v);
|
||||
it.width := ftw*length(v)+10;
|
||||
nitem[ti++] := it;
|
||||
end
|
||||
if not nitem then return 0;
|
||||
len := FTabItems.length();
|
||||
if not(idx>=0 and idx<=len) then
|
||||
begin
|
||||
nidx := len;
|
||||
end else nidx := idx;
|
||||
n := length(nitem);
|
||||
if FCurrentid >=idx then FCurrentid+=n;
|
||||
FTabItems.splices(nidx,0,nitem);
|
||||
lk := new tcountlocker(fclocker);
|
||||
for i:= nidx to nidx+n do
|
||||
measureidx(i);
|
||||
CalcTabs();
|
||||
InvalidateRect(nil,false);
|
||||
end
|
||||
function deltab(idx,n); virtual;//删除
|
||||
begin
|
||||
len := FTabItems.length()-1;
|
||||
if not( n>0) then n := 1;
|
||||
nidx := idx;
|
||||
if not(idx>=0 and idx<=len) then
|
||||
begin
|
||||
return 0;
|
||||
end
|
||||
if not(idx>=0 and idx<=len) then
|
||||
begin
|
||||
nidx := len;
|
||||
end else nidx := idx;
|
||||
FTabItems.splice(nidx,n);
|
||||
CalcTabs();
|
||||
if FCurrentid >(idx+n-1) then
|
||||
begin
|
||||
FCurrentid -=n;
|
||||
InvalidateRect(nil,false);
|
||||
end else
|
||||
if FCurrentid>=idx and FCurrentid<(idx+n-1) then
|
||||
begin
|
||||
FCurrentid := -1;
|
||||
setselidx( max(0,idx-1));
|
||||
end
|
||||
end
|
||||
function DesigningClick();override;
|
||||
begin
|
||||
return true;
|
||||
end
|
||||
function create(aowner);
|
||||
begin
|
||||
inherited;
|
||||
fownerdraw := 0;
|
||||
tabheight := 25;
|
||||
end
|
||||
function AfterConstruction();override;
|
||||
begin
|
||||
inherited;
|
||||
fclocker := new tcountkernel();
|
||||
color := 0xffffff;
|
||||
height := 200;
|
||||
width := 200;
|
||||
left := 10;
|
||||
top := 10;
|
||||
FTabPosition := alTop;
|
||||
FirstViewIndex := 0;
|
||||
FCurrentid := -1;
|
||||
FPrevid := -1;
|
||||
FTabItems := new tnumindexarray();
|
||||
end
|
||||
|
||||
Function SetCurSel(id); //设置当前序号
|
||||
begin
|
||||
if ifnumber(id) and id>=0 then
|
||||
begin
|
||||
iid := integer(id);
|
||||
setselidx(iid);
|
||||
end
|
||||
end
|
||||
function paint();override; //绘制
|
||||
begin
|
||||
PaintTabs();
|
||||
PaintScroll();
|
||||
end
|
||||
function MouseUp(o,e);override;//鼠标弹起
|
||||
begin
|
||||
if csDesigning in ComponentState then return;
|
||||
if e.skip then return ;
|
||||
ps := e.pos();
|
||||
mb := e.button();
|
||||
if (mb=mbLeft) and FScrollBtnRect and pointinrect(ps,fnextrect) then
|
||||
begin
|
||||
if e.Button() = mbLeft then
|
||||
ScrollNext();
|
||||
return ;
|
||||
end else
|
||||
if (mb=mbLeft) and FScrollBtnRect and pointinrect(ps,Fprevrect) then
|
||||
begin
|
||||
if e.Button() = mbLeft then
|
||||
scrollprev();
|
||||
return ;
|
||||
end
|
||||
if not FTabRects then return ;
|
||||
for i := 0 to length( FTabRects)-1 do
|
||||
begin
|
||||
v := FTabRects[i];
|
||||
if v and pointinrect(ps,v) then
|
||||
begin
|
||||
setselidx(i);
|
||||
if Onclick and (mb = mbLeft) then
|
||||
begin
|
||||
CallMessgeFunction(Onclick,o,e);
|
||||
end else
|
||||
if onrclick and (mb = mbRight) then
|
||||
begin
|
||||
CallMessgeFunction(onrclick,o,e);
|
||||
end
|
||||
return ;
|
||||
end
|
||||
//
|
||||
end
|
||||
end
|
||||
function doonSelChange(o,e);virtual;
|
||||
begin
|
||||
CallMessgeFunction(FOnSelChanged,o,e);
|
||||
end
|
||||
function doonSelChanging(o,e);virtual;
|
||||
begin
|
||||
CallMessgeFunction(fOnSelChanging,o,e);
|
||||
end
|
||||
function TabRect(AIndex: Integer); //获取区域
|
||||
begin
|
||||
r := FTabRects[AIndex];
|
||||
if r then return r;
|
||||
return array(0,0,0,0);
|
||||
end
|
||||
function DoControlAlign();override;//调整位置
|
||||
begin
|
||||
CalcTabs();
|
||||
end
|
||||
function gettabbyidx(idx);
|
||||
begin
|
||||
return FTabItems[idx];
|
||||
end
|
||||
{**
|
||||
@param(tabindex)(integer) 当前选中序号 %%
|
||||
@param(tabsheet)(tcustomtabsheet) 通过下标获得页面 %%
|
||||
@param(TabCount)(integer) page数量 %%
|
||||
@param(OnSelChange)(function[tcustompagecontrol,tuieventbase]) 标签已经切换 %%
|
||||
@param(OnSelChanging)(function[tcustompagecontrol,tuieventbase]) 标签正在切换 %%
|
||||
**}
|
||||
published
|
||||
property tabs:strings read gettabs write settabs;
|
||||
property tabindex:lazyinteger read FCurrentid write SetCurSel;
|
||||
property OnSelChanged:eventhandler read FOnSelChanged write FOnSelChanged;
|
||||
property OnSelChanging:eventhandler read FOnSelChanging write FOnSelChanging;
|
||||
property ondrawtab:eventhandler read Fondrawtab write fondrawtab;
|
||||
property ownerdraw:bool read fownerdraw write fownerdraw;
|
||||
property onmeasuretabwidth:eventhandler read fonmeasuretabwidth write fonmeasuretabwidth;
|
||||
property tabcount:integer read gettabcount ;
|
||||
property tabheight:integer read ftabheight write settabheight;
|
||||
property TabPosition read FTabPosition write SetTabPosition;
|
||||
property tabwidth read gettabwidth write settabwidth;
|
||||
private
|
||||
function gettabs();
|
||||
begin
|
||||
r := array();
|
||||
for i := 0 to FTabItems.length()-1 do
|
||||
begin
|
||||
r[i] := FTabItems[i].caption;
|
||||
end
|
||||
return r;
|
||||
end
|
||||
function gettabcount();
|
||||
begin
|
||||
return ftabitems.length();
|
||||
end
|
||||
function settabwidth(idx,w);
|
||||
begin
|
||||
if idx>0 and idx<ftabitems.length() and w>=0 and ftabitems[idx].width<>w then
|
||||
begin
|
||||
ftabitems[idx].width := w;
|
||||
end
|
||||
end
|
||||
function gettabwidth(idx);
|
||||
begin
|
||||
tb := ftabitems[idx];
|
||||
if tb then
|
||||
return tb.width;
|
||||
return nil;
|
||||
end
|
||||
function settabheight(h);
|
||||
begin
|
||||
if h>0 and h<>FTabHeight then
|
||||
begin
|
||||
ftabheight := h;
|
||||
CalcTabs();
|
||||
end
|
||||
end
|
||||
function settabs(tbs);
|
||||
begin
|
||||
if not ifarray(tbs) then return 0;
|
||||
if tbs=gettabs() then return 0;
|
||||
mtabitems := new tnumindexarray();
|
||||
ftw := font.width;
|
||||
for i,v in tbs do
|
||||
begin
|
||||
if not ifstring(v) then return 0;
|
||||
it := new t_tab_item(v);
|
||||
it.width := ftw*length(v)+10;
|
||||
mtabitems.Push(it);
|
||||
end
|
||||
FTabItems := mtabitems;
|
||||
FirstViewIndex := 0;
|
||||
FCurrentid := -1;
|
||||
FPrevid := -1;
|
||||
lk := new tcountlocker(fclocker);
|
||||
for i :=0 to n-1 do
|
||||
begin
|
||||
measureidx(i);
|
||||
end
|
||||
CalcTabs();
|
||||
InvalidateRect(nil,false);
|
||||
end
|
||||
function measureidx(i);//测量
|
||||
begin
|
||||
if onmeasuretabwidth then
|
||||
begin
|
||||
e := new tuieventbase(0,0,i,0);
|
||||
CallMessgeFunction(onmeasuretabwidth,e); //wparam 为序号
|
||||
if e.lparam>=0 then
|
||||
begin
|
||||
FTabItems[i].width := e.lparam;
|
||||
end
|
||||
end
|
||||
end
|
||||
private
|
||||
fownerdraw;
|
||||
[weakref]fondrawtab;
|
||||
[weakref]fonmeasuretabwidth;
|
||||
end
|
||||
|
||||
|
||||
|
||||
type tcustomtabsheet = class(TCustomControl) //控件页面
|
||||
{**
|
||||
@explan(说明)page控件页面 %%
|
||||
@@ -646,16 +88,27 @@ type tcustompagecontrol = class(TCustomControl)
|
||||
function CalcTabs(); //计算区域
|
||||
begin
|
||||
rec := ClientRect; //区域
|
||||
fclosebtnrect := array();
|
||||
ft := font;
|
||||
fw := ft.width;
|
||||
fh := ft.height;
|
||||
FTabHeight := fh+7;
|
||||
if not fownerdraw then
|
||||
begin
|
||||
fh := ft.height;
|
||||
FTabHeight := fh+7;
|
||||
end
|
||||
FTabItemswidth := array();
|
||||
e := new tuieventbase(0,0,0,0);
|
||||
for i := 0 to FTabItems.length()-1 do
|
||||
begin
|
||||
pg := FTabItems[i];
|
||||
ta := pg.Caption;
|
||||
FTabItemswidth[i] := max(20, length(ta)*fw+10 );
|
||||
FTabItemswidth[i] := max(20, length(ta)*fw+10 );
|
||||
if fonmeasuretabwidth then
|
||||
begin
|
||||
e.wparam := i;
|
||||
CallMessgeFunction(fonmeasuretabwidth,self(true),e);
|
||||
if e.lparam>=0 then FTabItemswidth[i] := e.lparam;
|
||||
end
|
||||
end
|
||||
FMaxsize := 0;
|
||||
if FTabPosition in array(alLeft,alRight) then
|
||||
@@ -665,7 +118,7 @@ type tcustompagecontrol = class(TCustomControl)
|
||||
end else
|
||||
begin
|
||||
FMaxsize := sum(FTabItemswidth);
|
||||
end
|
||||
end
|
||||
FClientarea := rec;
|
||||
FScrollBtnRect := 0;
|
||||
Fprevrect := 0;
|
||||
@@ -675,7 +128,7 @@ type tcustompagecontrol = class(TCustomControl)
|
||||
alLeft:
|
||||
begin
|
||||
if FTabItemswidth then
|
||||
begin
|
||||
begin
|
||||
FClientarea[0] :=rec[0]+FTabItemswidth[0];
|
||||
if length(FTabItemswidth)>1 and (FMaxsize>(rec[3]-rec[1])) then
|
||||
begin
|
||||
@@ -725,14 +178,20 @@ type tcustompagecontrol = class(TCustomControl)
|
||||
end
|
||||
end
|
||||
alTop:
|
||||
begin
|
||||
begin
|
||||
if FTabItemswidth then
|
||||
begin
|
||||
begin
|
||||
|
||||
FClientarea[1] :=rec[1]+FTabHeight;
|
||||
if length(FTabItemswidth)>1 and (FMaxsize>(rec[2]-rec[0])) then
|
||||
if fclosebtn then
|
||||
begin
|
||||
cbt := max(0,integer((FTabHeight-16)/2));
|
||||
fclosebtnrect := array(rec[2]-18,cbt,rec[2]+2,cbt+16);
|
||||
rec[2]-=21;
|
||||
end
|
||||
if length(FTabItemswidth)>1 and (FMaxsize>(rec[2]-rec[0]-(fclosebtn?20:0))) then
|
||||
begin
|
||||
FScrollBtnRect := array(rec[2]-FTabHeight*2,rec[1],rec[2],rec[1]+FTabHeight);
|
||||
|
||||
FScrollBtnRect := array(rec[2]-FTabHeight*2,rec[1],rec[2],rec[1]+FTabHeight);
|
||||
Fnextrect := array(rec[2]-FTabHeight,rec[1],rec[2],rec[1]+FTabHeight);
|
||||
Fprevrect := array(rec[2]-FTabHeight*2,rec[1],rec[2]-FTabHeight,rec[1]+FTabHeight);
|
||||
end else FirstViewIndex := 0;
|
||||
@@ -829,22 +288,35 @@ type tcustompagecontrol = class(TCustomControl)
|
||||
end
|
||||
function PaintTabs();//绘制tab
|
||||
begin
|
||||
lk := new tcountlocker(fclocker);
|
||||
dc := Canvas;
|
||||
dc.font := font;
|
||||
for i := 0 to FTabItems.length()-1 do
|
||||
ar := 0->(FTabItems.length()-1);
|
||||
if FTabRects[FCurrentid] then
|
||||
begin
|
||||
ar[FCurrentid] := -100;
|
||||
ar[length(ar)] := FCurrentid;
|
||||
end
|
||||
for ii,i in ar do
|
||||
begin
|
||||
rec := FTabRects[i];
|
||||
dc.pen.color := 13158600;//rgb(200,200,200);
|
||||
if rec then
|
||||
begin
|
||||
begin
|
||||
if fownerdraw and fondrawtab then
|
||||
begin
|
||||
e := new teventdrawtab(i,(FCurrentid=i),rec,dc);
|
||||
CallMessgeFunction(fondrawtab,self(true),e);
|
||||
continue;
|
||||
end
|
||||
dc.pen.color := 13158600;//rgb(200,200,200);
|
||||
if FCurrentid=i then
|
||||
begin
|
||||
dc.brush.color := 0xf0f0f0;//rgb(100,192,250);//rgb(230,240,250);//rgb(200,200,200);
|
||||
end else dc.brush.color := 16711422;//rgb(254,254,254);
|
||||
dc.draw("roundrect",array(rec[0:1],rec[2:3],array(2,2)));
|
||||
//dc.draw("rectangle",array(rec[0:1],rec[2:3],array(5,5)));
|
||||
rec[1]+=2;
|
||||
dc.drawtext(FTabItems[i].Caption,rec,DT_CENTER .|DT_VCENTER);
|
||||
it := FTabItems[i];
|
||||
dc.drawtext(it.caption,rec,DT_CENTER .|DT_VCENTER);
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -869,6 +341,16 @@ type tcustompagecontrol = class(TCustomControl)
|
||||
end
|
||||
end
|
||||
end
|
||||
if fclosebtnrect then
|
||||
begin
|
||||
dc.brush.color := 0x0000ff;
|
||||
dc.FillRect(fclosebtnrect);
|
||||
dc.pen.color := 0xf0f0f0;
|
||||
dc.moveto(fclosebtnrect[0:1]);
|
||||
dc.LineTo(fclosebtnrect[2:3]);
|
||||
dc.moveto(array(fclosebtnrect[2],fclosebtnrect[1]));
|
||||
dc.LineTo(array(fclosebtnrect[0],fclosebtnrect[3]));
|
||||
end
|
||||
end
|
||||
function ScrollPrev(); //滚动到下一个
|
||||
begin
|
||||
@@ -965,7 +447,30 @@ type tcustompagecontrol = class(TCustomControl)
|
||||
inherited;
|
||||
DoControlAlign();
|
||||
end
|
||||
|
||||
function hittabat(xy); //命中
|
||||
begin
|
||||
r := array();
|
||||
if (FScrollBtnRect and pointinrect(xy,FScrollBtnRect)) then
|
||||
begin
|
||||
r["idx"] := "scroll";
|
||||
return r;
|
||||
end
|
||||
if (fclosebtnrect and pointinrect(xy,fclosebtnrect)) then
|
||||
begin
|
||||
r["idx"] := "closebtn";
|
||||
return r;
|
||||
end
|
||||
for i,v in FTabRects do
|
||||
begin
|
||||
if v and pointinrect(xy,v) then
|
||||
begin
|
||||
r["idx"] := i;
|
||||
r["pos"] := array(xy[0]-v[0],xy[1]-v[1]);
|
||||
return r;
|
||||
end
|
||||
end
|
||||
return r;
|
||||
end
|
||||
function getsheetrect(); //获得sheet
|
||||
begin
|
||||
{**
|
||||
@@ -981,7 +486,11 @@ type tcustompagecontrol = class(TCustomControl)
|
||||
end
|
||||
function create(aowner);
|
||||
begin
|
||||
inherited;
|
||||
inherited;
|
||||
fclosebtn := false;
|
||||
FTabHeight := font.height+7;
|
||||
faccepttype := array();
|
||||
acceptsheettype(class(tcustomtabsheet));
|
||||
end
|
||||
function AfterConstruction();override;
|
||||
begin
|
||||
@@ -1000,19 +509,19 @@ type tcustompagecontrol = class(TCustomControl)
|
||||
end
|
||||
function ControlAppended(AControl);override;
|
||||
begin
|
||||
if not(AControl is class(tcustomtabsheet)) then return;
|
||||
if not isacceptsheettype(AControl) {not(AControl is class(tcustomtabsheet))} then return;
|
||||
addtabitem(AControl);
|
||||
end
|
||||
function ControlDeleted(AControl);override;
|
||||
begin
|
||||
if not(AControl is class(tcustomtabsheet)) then return;
|
||||
if not isacceptsheettype(AControl){ not(AControl is class(tcustomtabsheet))} then return;
|
||||
id := GetPageID(AControl);
|
||||
RemovePageTab(id);
|
||||
//fcoolbands.deleteitem(AControl,true);
|
||||
end
|
||||
Function SetCurSel(id); //设置当前序号
|
||||
begin
|
||||
if id is class(tcustomtabsheet) then
|
||||
if isacceptsheettype(id) {id is class(tcustomtabsheet)} then
|
||||
begin
|
||||
return SetCurSel(GetPageID(id));
|
||||
end
|
||||
@@ -1029,20 +538,29 @@ type tcustompagecontrol = class(TCustomControl)
|
||||
end
|
||||
function MouseUp(o,e);override;//鼠标弹起
|
||||
begin
|
||||
if e.skip then return ;
|
||||
ps := e.pos();
|
||||
mb := e.button();
|
||||
//if mb=mbRight then return ;
|
||||
if (mb=mbLeft) and FScrollBtnRect and pointinrect(ps,fnextrect) then
|
||||
begin
|
||||
if e.Button() = mbLeft then
|
||||
ScrollNext();
|
||||
return ;
|
||||
end else
|
||||
if (mb=mbLeft) and FScrollBtnRect and pointinrect(ps,Fprevrect) then
|
||||
begin
|
||||
if e.Button() = mbLeft then
|
||||
scrollprev();
|
||||
return ;
|
||||
if(mb=mbLeft) then
|
||||
begin
|
||||
if fclosebtn and fclosebtnrect and pointinrect(ps,fclosebtnrect) then
|
||||
begin
|
||||
if fonclosebtnclick then
|
||||
begin
|
||||
e := new tuieventbase(0,0,0,0);
|
||||
CallMessgeFunction(fonclosebtnclick,self(true),e);
|
||||
end
|
||||
return ;
|
||||
end
|
||||
if FScrollBtnRect and pointinrect(ps,fnextrect) then
|
||||
begin
|
||||
return ScrollNext();
|
||||
end
|
||||
if FScrollBtnRect and pointinrect(ps,Fprevrect) then
|
||||
begin
|
||||
return scrollprev();
|
||||
end
|
||||
end
|
||||
if not FTabRects then return ;
|
||||
for i := 0 to length( FTabRects)-1 do
|
||||
@@ -1090,7 +608,7 @@ type tcustompagecontrol = class(TCustomControl)
|
||||
@explan(说明)获取page的序号 %%
|
||||
**}
|
||||
r := -1;
|
||||
if page is class(tcustomtabsheet) then
|
||||
if {page is class(tcustomtabsheet)} isacceptsheettype(page) then
|
||||
begin
|
||||
for it := 0 to FTabItems.length()-1 do
|
||||
begin
|
||||
@@ -1174,6 +692,22 @@ type tcustompagecontrol = class(TCustomControl)
|
||||
FOnSelChanging := nil;
|
||||
FTabItems.splice(0,nil);
|
||||
inherited;
|
||||
end
|
||||
function acceptsheettype(ty,del);
|
||||
begin
|
||||
idx := 0;
|
||||
if ty is class(tcontrol) then
|
||||
begin
|
||||
idx := inttostr(int64(ty));
|
||||
end
|
||||
if idx = 0 then return 0;
|
||||
if del then
|
||||
begin
|
||||
reindex(faccepttype,array(idx:nil));
|
||||
end else
|
||||
begin
|
||||
faccepttype[idx] := ty;
|
||||
end
|
||||
end
|
||||
{**
|
||||
@param(cursel)(integer) 当前选中序号 %%
|
||||
@@ -1192,6 +726,45 @@ type tcustompagecontrol = class(TCustomControl)
|
||||
property TabCount read GetTabCount;
|
||||
property TabPosition:tabalign read FTabPosition write SetTabPosition;
|
||||
property tabsheet read gettabesheet ;
|
||||
property onmeasuretabwidth:eventhandler read fonmeasuretabwidth write fonmeasuretabwidth;
|
||||
property ondrawtab:eventhandler read fondrawtab write fondrawtab;
|
||||
property ownerdraw:bool read fownerdraw write fownerdraw;
|
||||
property tabheight:lazyinteger read FTabHeight write settabheight;
|
||||
property closebtn:bool read fclosebtn write setclosebtn;
|
||||
property onclosebtnclick:eventhandler read fonclosebtnclick write fonclosebtnclick;
|
||||
private
|
||||
fownerdraw;
|
||||
faccepttype;
|
||||
fclosebtn;
|
||||
fclosebtnrect;
|
||||
[weakref] fondrawtab;
|
||||
[weakref] fonmeasuretabwidth;
|
||||
[weakref] fonclosebtnclick;
|
||||
private
|
||||
function isacceptsheettype(c);
|
||||
begin
|
||||
for i,v in faccepttype do
|
||||
begin
|
||||
if c is v then return true;
|
||||
end
|
||||
end
|
||||
function setclosebtn(v);
|
||||
begin
|
||||
nv := v?true:false;
|
||||
if nv<>fclosebtn then
|
||||
begin
|
||||
fclosebtn := nv;
|
||||
DoControlAlign();
|
||||
end
|
||||
end
|
||||
function settabheight(h);
|
||||
begin
|
||||
if ownerdraw and ( h>=0) and FTabHeight<>h then
|
||||
begin
|
||||
FTabHeight := h;
|
||||
DoControlAlign();
|
||||
end
|
||||
end
|
||||
end
|
||||
implementation
|
||||
type tcustomtabitem = class() //
|
||||
@@ -1215,7 +788,7 @@ type tcustomtabitem = class() //
|
||||
if ifstring(s) and s<>FCaption then
|
||||
begin
|
||||
FCaption := s;
|
||||
if PageSheet is class(tcustomtabsheet) then PageSheet.Caption := s;
|
||||
if PageSheet then PageSheet.Caption := s;
|
||||
end
|
||||
end
|
||||
public
|
||||
@@ -1227,11 +800,12 @@ type tcustomtabitem = class() //
|
||||
published
|
||||
property Caption read FCaption write SetCaption;
|
||||
property PageSheet read FPageSheet Write FPageSheet;
|
||||
_tag;
|
||||
end
|
||||
type teventdrawtab = class(tuieventbase)
|
||||
{**
|
||||
@explan(说明)单元格绘制消息对象 %%
|
||||
@param(idx)(integer) 行号 %%
|
||||
@param(idx)(integer) 序号 %%
|
||||
@param(sel)(integer) 是否选中 %%
|
||||
@param(rec)(array(左上右下)) 区域 %%
|
||||
@param(canvas)(TCanvas) 画布 %%
|
||||
@@ -1249,17 +823,6 @@ type teventdrawtab = class(tuieventbase)
|
||||
rec;
|
||||
canvas;
|
||||
end
|
||||
type t_tab_item = class()
|
||||
function create(s);
|
||||
begin
|
||||
if ifstring(s) then
|
||||
caption := s;
|
||||
else caption := "";
|
||||
end
|
||||
_Tag;
|
||||
caption;
|
||||
width;
|
||||
end
|
||||
initialization
|
||||
|
||||
end.
|
||||
@@ -3180,6 +3180,21 @@ type TCustomListBoxbase=class(TCustomScrollControl)
|
||||
end
|
||||
return array();
|
||||
end
|
||||
function hititemat(xy);
|
||||
begin
|
||||
r := array();
|
||||
if not(ifarray(xy) and ifnumber(xy[0]) and ifnumber(xy[1])) then return r;
|
||||
y := xy[1];
|
||||
idx := GetIdxByYpos(y);
|
||||
if idx>=0 then
|
||||
begin
|
||||
rc := GetIdxRect(idx);
|
||||
r["idx"] := idx;
|
||||
r["x"] := x-rc[0];
|
||||
r["y"] := y-rc[1];
|
||||
end
|
||||
return r;
|
||||
end
|
||||
function InsureIdxInClient(idx); //确保指定项在区域中
|
||||
begin
|
||||
{**
|
||||
@@ -3367,6 +3382,7 @@ type TcustomListBox=class(TCustomListBoxbase)
|
||||
function MouseDown(o,e);override;
|
||||
begin
|
||||
if csDesigning in ComponentState then return;
|
||||
if e.skip then return ;
|
||||
if(e.Button()=mbLeft)and not(e.shiftdouble())then
|
||||
begin
|
||||
FFormerSelBegin := FSelBegin;
|
||||
@@ -3446,7 +3462,20 @@ type TcustomListBox=class(TCustomListBoxbase)
|
||||
nh := min(h,16);
|
||||
nnh := integer((h-nh)/2);
|
||||
rc2 := array(rc[0]+2,rc[1]+nnh,rc[0]+nh+2,rc[3]-nnh);
|
||||
cvs.Draw("framecontrol",array(rc2[0:1],rc2[2:3]),DFC_BUTTON,(r)?DFCS_CHECKED:DFCS_BUTTONCHECK);
|
||||
if fcheckbox=2 then
|
||||
begin
|
||||
cvs.Draw("framecontrol",array(rc2[0:1],rc2[2:3]),DFC_BUTTON,DFCS_BUTTONRADIO);
|
||||
if r then
|
||||
begin
|
||||
r2 := array(rc2[0:1]+3,rc2[2:3]-3);
|
||||
cvs.brush.color := 0;
|
||||
cvs.draw("ellipse",r2);
|
||||
end
|
||||
//cvs.Draw("framecontrol",array(rc2[0:1],rc2[2:3]),DFC_BUTTON,(r)?DFCS_CHECKED:DFCS_BUTTONCHECK);
|
||||
end else
|
||||
begin
|
||||
cvs.Draw("framecontrol",array(rc2[0:1],rc2[2:3]),DFC_BUTTON,(r)?DFCS_CHECKED:DFCS_BUTTONCHECK);
|
||||
end
|
||||
rc1[0]+=nh+5;
|
||||
end
|
||||
PaintIdexText(idx,rc1,cvs);
|
||||
@@ -3880,10 +3909,9 @@ type TcustomListBox=class(TCustomListBoxbase)
|
||||
end
|
||||
function setcheckbox(c);
|
||||
begin
|
||||
nc := c?true:false;
|
||||
if nc<>fcheckbox then
|
||||
if c<>fcheckbox and (c in array(0,1,2)) then
|
||||
begin
|
||||
fcheckbox := nc;
|
||||
fcheckbox := c;
|
||||
InvalidateRect(nil,false);
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user