1. Programming Challenge: Reordering and Renumbering Control definitions
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> Mar 26, 2005
- 550 views
Hi all, I am hoping someone will enjoy a little challenge, though bear in mind this will be closed source. I am aware that I am being a little cheeky asking for help... I think it is an interesting problem anyway. The problem is that Euphoria has no forward definitions, so all parents must be defined before all child controls. Normally not a problem, but if I want to allow a control, in a long list, to change parent, I have to reorder, and renumber. Controls can be deeply nested, but are held in a flat list. Something recursive is probably required. Maybe it is wishful thinking, but I have a gut feeling the answer will be relatively trivial, I just can't see it. I've written a little test harness, obviously you are allowed to add as many variables and routines as you think you need. The only thought of note I have had so far is a function numberOfChildren(x,y) which (recursively) counts children of x occuring before entry y. Whether that is helpful or not is a matter for you to answer. Speed is not an issue; the algorithm can be as inefficient as you like, but of course it must deliver the correct results. Each entry in CtrlSet is {name, parent, list of children} The order of the children is not strictly important, if you need to, sort() them, or use a variation of the commented out code in CtrlChk. Equally, the final order of the controls is slightly flexible, providing they still follow the obvious rules.
sequence CtrlSet procedure CtrlChk(sequence Chk) if not equal(CtrlSet,Chk) then ?9/0 end if -- for i =1 to length(Chk) do -- if Chk[i][2] >= i then ?9/0 end if -- for j = 1 to length(Chk[i][3]) do -- if Chk[i][3][j]<=i then ?9/0 end if -- end for -- end for end procedure procedure makeChildOf(integer id, integer newPID) end procedure CtrlSet={{"Main",0,{2,3,4,6}}, -- Button,Group,Label,TabControl {"Button",1,{}}, {"Group",1,{5}}, -- Label2 {"Label",1,{}}, {"Label2",3,{}}, {"TabControl",1,{7}}, -- TabItem {"TabItem",6,{}}} makeChildOf(3,7) -- move Group onto TabItem --==> CtrlChk({{"Main",0,{2,3,4}}, -- Button,Label,TabControl {"Button",1,{}}, {"Label",1,{}}, {"TabControl",1,{5}}, -- TabItem {"TabItem",4,{6}}, -- Group {"Group",5,{7}}, -- Label2 {"Label2",6,{}}}) makeChildOf(2,5) -- move Button onto TabItem --==> CtrlChk({{"Main",0,{2,3}}, -- Label,TabControl {"Label",1,{}}, {"TabControl",1,{4}}, -- TabItem {"TabItem",3,{5,6}}, -- Group,Button {"Button",4,{}}, {"Group",5,{7}}, -- Label2 {"Label2",6,{}}}) makeChildOf(6,1) -- move Group off TabItem --==> CtrlChk({{"Main",0,{2,3,6}}, -- Label, TabControl, Group {"Label",1,{}}, {"TabControl",1,{4}}, -- TabItem {"TabItem",3,{5}}, -- Button {"Button",4,{}}, {"Group",1,{7}}, -- Label2 {"Label2",6,{}}}) makeChildOf(3,6) -- move TabControl onto Group --==> CtrlChk({{"Main",0,{2,3}}, -- Label,Group {"Label",1,{}}, {"Group",1,{4,7}}, -- TabControl,Label2 {"TabControl",3,{5}}, -- TabItem {"TabItem",4,{6}}, -- Button {"Button",5,{}}, {"Label2",3,{}}}) --
My apologies if I made any minor glitch in any of those numbers, (which I am sure I have) Regards, and above all, have fun with it, Pete
2. Re: Programming Challenge: Reordering and Renumbering Control definitions
- Posted by Al Getz <Xaxo at aol.com> Mar 26, 2005
- 545 views
Hi there Pete, Ooooh...closed source.....shame, shame! (hee hee) Really, although most of the stuff i share is open i keep a few things closed too just so i can say "That's mine" pretty much Not like there's anything secret or something, so i understand completely. Im not sure if this helps or not, but if it's Windowses programming you might try HWND SetParent(hwndChild,hwndNewParent) in user32.dll I dont know for sure if this will do what you need, but i thought i would mention it cause it sounds similar to what you are asking. Take care, Al And, good luck with your Euphoria programming! My bumper sticker: "I brake for LED's"
3. Re: Programming Challenge: Reordering and Renumbering Control definitions
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> Mar 26, 2005
- 541 views
On Fri, 25 Mar 2005 18:46:04 -0800, Al Getz <guest at RapidEuphoria.com> wrote: >Im not sure if this helps or not, but if it's Windowses programming >you might try > >HWND SetParent(hwndChild,hwndNewParent) > >in user32.dll > >I dont know for sure if this will do what you need, but i thought Yes, I've already used that (and it works), the problem is if I output eg: constant btn6=create(Button,"text",grp7,...) constant grp7=... I'll get an error - grp7 has not been declared. I've had a few more ideas, I'll try them out today. Thanks, Pete
4. Re: Programming Challenge: Reordering and Renumbering Control definitions
- Posted by Al Getz <Xaxo at aol.com> Mar 26, 2005
- 522 views
Hi again Pete, Let me see if i understand you now... You're saying you want to create say several buttons and then create say a tab (for a tab in say a property sheet or for a pager) BEFORE you create the tab or even the property sheet or pager? Like: B1=create(button,dummy,...) B2=create(button,dummy,...) B3=create(button,dummy,...) PS1=create(PropertySheet,MainWindow...) Tab1=create(Tab,PS1,...) Tab2=create(Tab,PS1,...) In the above the tabs have no problem because the parent (PS1) has been created before the two tab items, but the three buttons dont have a home yet because PS1 hasnt yet been created and neither has their tab item(s). If i understand you correctly this is the problem you were talking about. Im trying to remember why this works ok in my WinClass lib, but another idea would be to assign the three buttons to a dummy (and non-visible) window until after the appropriate parent is created. I guess you could wrap the parent creation (the create function itself) to allow adding childs at create time or simply make a new function to add controls to a parent once the parent has been created. This forces everything to clock properly whether the child is created before or after the parent. I guess we are all used to assigning the parent at the same time we create the child, but then for some of my tab items (in my next function calculator version) im assigning one control to several parents without a problem (maybe because there's one real parent and several virtual parents) but im sure with your own function you can do the same. Just some more ideas...feel free to comment. Pete Lomax wrote: > > On Fri, 25 Mar 2005 18:46:04 -0800, Al Getz <guest at RapidEuphoria.com> > wrote: > > >Im not sure if this helps or not, but if it's Windowses programming > >you might try > > > >HWND SetParent(hwndChild,hwndNewParent) > > > >in user32.dll > > > >I dont know for sure if this will do what you need, but i thought > Yes, I've already used that (and it works), the problem is if I output > eg: > constant btn6=create(Button,"text",grp7,...) > constant grp7=... > > I'll get an error - grp7 has not been declared. > > I've had a few more ideas, I'll try them out today. > > Thanks, > Pete > > Take care, Al And, good luck with your Euphoria programming! My bumper sticker: "I brake for LED's"
5. Re: Programming Challenge: Reordering and Renumbering Control definitions
- Posted by "Juergen Luethje" <j.lue at gmx.de> Mar 26, 2005
- 513 views
Pete Lomax wrote: > Hi all, > > I am hoping someone will enjoy a little challenge, though bear in mind > this will be closed source. I am aware that I am being a little > cheeky asking for help... I disagree, I don't consider it cheeky for several reasons. > I think it is an interesting problem anyway. > > The problem is that Euphoria has no forward definitions, so all > parents must be defined before all child controls. Normally not a > problem, but if I want to allow a control, in a long list, to change > parent, I have to reorder, and renumber. Controls can be deeply > nested, but are held in a flat list. Something recursive is probably > required. I don't think that I've understood the situation completely ... But maybe a Topological Sort would be helpful: http://www.brpreiss.com/books/opus4/html/page557.html#SECTION0017330000000000000000 Recently I wrote a little Eu function that does Topological Sorting. If you want, I can (try to) translate the comments to English, and then post it here. <big snip> Regards, Juergen PS: Happy Easter to all (for whom it has a meaning)!
6. Re: Programming Challenge: Reordering and Renumbering Control definitions
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> Mar 26, 2005
- 572 views
On Sat, 26 Mar 2005 04:09:34 -0800, Al Getz <guest at RapidEuphoria.com> wrote: >Hi again Pete, > >Let me see if i understand you now... > >You're saying you want to create say several buttons and then >create say a tab (for a tab in say a property sheet or for a pager) BEFORE >you create the tab or even the property sheet or pager? Well sort of. Suppose I create a few buttons, and then decide they would look better in a group or on a tab. After moving them I wanted to shuffle the table so it was in a valid order to write out create statements. The answer I stumbled on this morning was four-phase: 1) mark the control being moved and all its children 2) allocate new positions for marked entries 3) allocate new positions for unmarked entries 4) repeatedly swap entries into place The code to do this is:
sequence renumber procedure markChildren(integer id, integer lim) -- -- mark id and any children, grandchildren, etc of id -- that occur before lim. -- renumber[id]=1 for i=id+1 to lim do if CtrlSet[i][2]=id then renumber[i]=1 markChildren(i,lim) end if end for end procedure procedure swap(integer i, integer k) sequence tmp -- -- swap the two entries -- tmp=CtrlSet[i] CtrlSet[i]=CtrlSet[k] CtrlSet[k]=tmp -- -- change any reference to i to k, and vice versa -- for j=1 to length(CtrlSet) do if CtrlSet[j][2]=i then CtrlSet[j][2]=k elsif CtrlSet[j][2]=k then CtrlSet[j][2]=i end if for l=1 to length(CtrlSet[j][3]) do if CtrlSet[j][3][l]=i then CtrlSet[j][3][l]=k elsif CtrlSet[j][3][l]=k then CtrlSet[j][3][l]=i end if end for end for -- -- lastly, [i] has been moved to it's final place (always), but -- [k] may or may not be, so check. -- if renumber[k]=i then -- 'perfect' swap renumber[i]=0 else -- only 'i' ended up in final home. renumber[i]=renumber[k] end if renumber[k]=0 end procedure include sort.e procedure makeChildOf(integer id, integer newPID) integer k, oldPID sequence oldChildren oldPID=CtrlSet[id][2] oldChildren=CtrlSet[oldPID][3] k=find(id,oldChildren) oldChildren=oldChildren[1..k-1]&oldChildren[k+1..length(oldChildren)] CtrlSet[oldPID][3]=oldChildren CtrlSet[id][2]=newPID CtrlSet[newPID][3]=sort(CtrlSet[newPID][3]&id) if id<newPID then -- -- create a flag set, 1 for everything which must end up -- after newPID (wherever that ends up). -- renumber=repeat(0,length(CtrlSet)) markChildren(id,newPID) -- -- allocate new positions for all marked items in the range -- k=newPID for i=newPID to id by -1 do if renumber[i] then renumber[i]=k k-=1 end if end for -- -- allocate new positions for unmarked items in the range -- for i=newPID to id by -1 do if not renumber[i] then renumber[i]=k k-=1 end if end for for i=id to newPID do -- look for something to swap -- -- if renumber[i], then we move it to its final place, -- by swapping it with whatever is there. However -- whatever we swapped it with might still need -- moving. This is however guaranteed to terminate -- since we put at least one thing in it's final resting -- place every iteration. -- while renumber[i] do k=renumber[i] swap(i,k) end while end for end if end procedure
It's actually quite efficient, no worse than O(2n) when n controls need to be moved. Regards, Pete
7. Re: Programming Challenge: Reordering and Renumbering Control definitions
- Posted by Pete Lomax <petelomax at blueyonder.co.uk> Mar 26, 2005
- 567 views
On Sat, 26 Mar 2005 14:46:29 +0100, Juergen Luethje <j.lue at gmx.de> wrote: >I don't think that I've understood the situation completely ... >But maybe a Topological Sort would be helpful: Yes, that would probably work, if you built a translation table and ran through the table afterwards updating all the references. I would probably have used that if I had remembered what it was called, but I managed to invent a different solution this afternoon. Regards, Pete