delphi xe - TObjectList re-order -
i need re-order tobjectlist, according rules. how can achieve this?
so add panels scrollbox dinamically. when add them, add them objectlist in order added @ runtime, future use. can re-organize panels in scrollbox drag/drop. want objectlist mirror same order set @ runtime drag/drop.
here code:
var mainform: tmainform; panellist,panellisttmp:tobjectlist; implementation ... procedure tmainform.formcreate(sender: tobject); begin panellist:=tobjectlist.create; panellisttmp:=tobjectlist.create; end; procedure tmainform.button1click(sender: tobject); begin addpanel('0'); addpanel('1'); addpanel('2'); addpanel('3'); addpanel('4'); end; procedure tmainform.addpanel(what:string); var pan:tpanel; bv:tshape; begin pan:=tpanel.create(self); pan.parent:=thecontainer; pan.height:=50; pan.bevelouter:=bvnone; pan.borderstyle:=bsnone; pan.ctl3d:=false; pan.name:='layerpan'+what; pan.caption:=what; pan.align:=albottom; pan.onmousedown:=panmousedown; end; procedure tmainform.panmousedown(sender: tobject; button: tmousebutton;shift: tshiftstate; x, y: integer); var i:integer; idu:string; panui:tpanel; begin panui:=sender tpanel; panui.parentcolor:=false; panui.bringtofront; // drag drop stuff releasecapture; panui.perform(wm_nclbuttondown,htcaption,0); := 0 mainform.componentcount - 1 begin if mainform.components[i] twincontrol if twincontrol(mainform.components[i]) tpanel if (twincontrol(mainform.components[i]) tpanel).parent=mainform.thecontainer begin (twincontrol(mainform.components[i]) tpanel).align:=albottom; end; end; thecontainer.scrollinview(panui); reorderpanels; end; procedure tmainform.reorderpanels; begin end;
what should in reorderpanels procedure? thinking feeding panels of scrollbox bottom top new tobjectlist (panellisttmp), clear panellist , re-add them panellisttmp, when that, error: access violation, , einvalidpointer - invalid pointer operation
so thought:
procedure tmainform.reorderpanels; var ctrl:tcontrol; pos:tpoint; pan:tpanel; bad:boolean; ord,i:integer; begin memo2.lines.add('*** new order start'); panellisttmp.clear; // scroll top thecontainer.vertscrollbar.position := 0; // scroll down thecontainer.vertscrollbar.position := thecontainer.vertscrollbar.range; // panel pos:=thecontainer.clientorigin; pos.y:=pos.y+thecontainer.height-5; ctrl := findvclwindow(pos) ; if ctrl tpanel if tpanel(ctrl).parent = thecontainer begin pan:=(ctrl tpanel); panellisttmp.add(pan); end; ord:=1; bad:=false; repeat repeat pos.y:=pos.y-1; until (findvclwindow(pos) tpanel)and(findvclwindow(pos)<>pan); if (findvclwindow(pos) tpanel)and(findvclwindow(pos).name<>'layerpan') begin pan:=findvclwindow(pos) tpanel; containeru.vertscrollbar.position := 0; containeru.scrollinview(pan); ord:=ord+1; panellisttmp.add(pan); end else bad:=true; until bad=true; // , swap between objectlists... panellist.clear; i:=0 panellisttmp.count-1 begin (panellisttmp.items[i] tpanel).parent:=containeru; panellist.add(panellisttmp.items[i]); end; end;
so assume because objectlist storing pointers actual objects, when clear initial objectlist, actual objects freed, second objectlist contains list of pointers no longer viable... how can achieve want?
so on buttonclick, objectlist contains panels in following order:
panellist[0] - panel0 panellist[1] - panel1 panellist[2] - panel2 panellist[3] - panel3 panellist[4] - panel4
after drag - drop panels inside scrollbox, can end order (in scrollbox)
panel3 panel1 panel4 panel2 panel0
but in objectlist, order same before...
again, want able have objectlist ordered according order of panels scrollbox. in re-order procedure panels in desired order. need have them in same order in objectlist.
is there other way of doing this? other me creating new class hold index beside tpanel , use in objectlist maintain order?
tobjectlist
has ownsobjects
property true default. make sure set false since don't want list auto-free objects owned form.
as actual sorting of tobjectlist
, consider using sort()
or sortlist()
method that. after have repositioned panels desired within container, call sort()
or sortlist()
. sorting callback provide given 2 object pointers @ time while sorting iterating list. use current positions of objects relative each other tell list order should appear in.
try this:
var mainform: tmainform; panellist: tobjectlist; implementation ... procedure tmainform.formcreate(sender: tobject); begin panellist := tobjectlist.create(false); end; procedure tmainform.formdestroy(sender: tobject); begin panellist.free; end; procedure tmainform.button1click(sender: tobject); begin addpanel('0'); addpanel('1'); addpanel('2'); addpanel('3'); addpanel('4'); end; procedure tmainform.addpanel(what: string); var pan: tpanel; bv: tshape; begin pan := tpanel.create(self); try pan.parent := thecontainer; pan.height := 50; pan.bevelouter := bvnone; pan.borderstyle := bsnone; pan.ctl3d := false; pan.name := 'layerpan'+what; pan.caption := what; pan.align := albottom; pan.onmousedown := panmousedown; panellist.add(pan); except pan.free; raise; end; end; procedure tmainform.panmousedown(sender: tobject; button: tmousebutton; shift: tshiftstate; x, y: integer); var i: integer; idu: string; panui, pan: tpanel; tmplist: tobjectlist; begin panui := sender tpanel; panui.parentcolor := false; panui.bringtofront; // drag drop stuff releasecapture; panui.perform(wm_nclbuttondown, htcaption, 0); tmplist := tobjectlist.create(false); try := 0 thecontainer.controlcount - 1 begin if thecontainer.controls[i] tpanel tmplist.add(tpanel(thecontainer.controls[i])); end; := 0 tmplist.count - 1 tpanel(tmplist[i]).align := albottom; tmplist.free; end; thecontainer.scrollinview(panui); reorderpanels; end; function sortpanels(item1, item2: pointer): integer; begin result := tpanel(item2).top - tpanel(item1).top; end; procedure tmainform.reorderpanels; begin panellist.sort(sortpanels); // alternatively: { panellist.sortlist( function(item1, item2: pointer): integer; begin result := tpanel(item2).top - tpanel(item1).top; end ); } end;
Comments
Post a Comment