Page 1 of 4
Cards controls loop?
Posted: Thu Aug 08, 2024 7:42 am
by Zax
Hello,
I would like to search for all occurrences of a string in all scripts of a stack.
My first idea was
to loop over all cards in the stack, and then loop over all controls of that card. But the problem is that if some cards contain "behave like a background" groups, the controls of those groups will appear on all those cards - that's the principle of a background - and therefore my loop will contain repetitions in the occurrences found.
I don't know if I'm very clear, so here's a diagram of a stack as it appears in the Project Browser:
Code: Select all
MyStack
Card_1
Background_Group_A // Behave like a background
Btn_A_1
Btn_A_2
Background_Group_B // Behave like a background
Btn_B_1
Card_1_Group // card group
Fld_1
Card_2
Background_Group_A
Btn_A_1
Btn_A_2
Background_Group_B
Btn_B_1
My loop will search in the scripts of the control
Btn_A_1 of card Card_1, and also in the control
Btn_A_1 of card Card_2, which is an unnecessary repetition and produces duplicate results.
Of course, I could list the controls as I loop, and then test if the current control is already listed, but that seems a bit slow and crude. Is there a more elegant and faster way?
Re: Cards controls loop?
Posted: Thu Aug 08, 2024 10:00 am
by stam
I think backgrounds are not contained within cards - that's the point of them.
you could use
and iterate through these before iterating through cards and then normal groups.
You'd also need to iterate through substacks...
this graphic that shows a simplified message path I created a little while back may help:
Regards
Stam
Re: Cards controls loop?
Posted: Thu Aug 08, 2024 2:11 pm
by dunbarx
"Backgrounds" were a Hypercard object. LC changed that paradigm with groups.
But if your task is to find every occurrence of a string, it does not matter. You need only look at controls, cards and stacks. Those are the only repositories of scripts. I made this when I first changed over from HC to LC. It looks at all scripts in a stack and its substacks. You can modify it to find a string instead of just counting "active" lines and total number of lines in all scripts:
Code: Select all
on countLines
lock screen
set the cursor to busy
lock messages
repeat with y = 1 to the number of cds
put y && the number of controls of cd y into line y of tCon
put the script of cd y & return after accum
repeat with u = 1 to the number of controls of cd y
put the script of control u of cd y & return after accum
end repeat
end repeat
put the script of this stack after accum
put the substacks of this stack into stackList
repeat with v= 1 to the number of lines of stackList
go stack line v of stacklist
if the result <> "" then
end if
repeat with y = 1 to the number of cds
put the script of cd y & return after accum
repeat with u = 1 to the number of controls of cd y
put the script of control u of cd y & return after accum
end repeat
end repeat
put return & the script of this stack after accum
end repeat
repeat for each line tline in accum
if char 1 to 2 of tLine <> "--" and tLine <> "" then add 1 to numLines --COUNT ONLY WORKING LINES
add 1 to totLines
end repeat
repeat with v= 1 to the number of lines of stackList
close stack line v of stacklist
end repeat
answer "# active Lines:" && numLines & return & "Total Lines:" && totLines
end countLines
It occurs to me that widgets might be a fourth gadget to examine.
Craig
Re: Cards controls loop?
Posted: Thu Aug 08, 2024 3:02 pm
by richmond62
I would like to search for all occurrences of a string in all scripts of a stack.
-
-
I tend to use the built-in Find and Replace stack.
Re: Cards controls loop?
Posted: Thu Aug 08, 2024 3:47 pm
by dunbarx
Richmond.
The OP wants to find and collect ALL instances of a string in ALL objects that contain a script.
Craig
Re: Cards controls loop?
Posted: Thu Aug 08, 2024 5:09 pm
by stam
dunbarx wrote: ↑Thu Aug 08, 2024 2:11 pm
"Backgrounds" were a Hypercard object. LC changed that paradigm with groups.
Yes Craig, I am aware....
I was using the term "backgrounds" because I'm too lazy to type out "groups with background set to true".
But you got me typing it anyway...
Background groups
do not belong to cards, so you cannot easily iterate card objects for these.
This is why our beloved LiveCode provided us with the stack property
backgroundIDs
Dictionary wrote:Use the backgroundIDs property to find out which backgrounds are available.
The backgroundIDs is the list of all backgrounds in the stack whose backgroundBehavior property is set to true, whether they appear on the current card or not. If a group in the stack contains groups, only the top-level groups are reported.
To find out which groups are placed on a card, use the groupIDs property.
This also means that both background groups and normal groups need to be assessed for sub-groups as containers and all their children and iterate through those as well.
Re: Cards controls loop?
Posted: Thu Aug 08, 2024 5:19 pm
by stam
Craig, just glanced at your script.
You don't seem to be accounting for scripts in groups and background groups (as containers, not their children) and as mentioned you're also not accounting for children of background containers.
Groups can contain subgroups which also have their own scripts and so on.
The card property GroupIDs and the stack property BackgroundIDs should allow you to iterate through those as well.
Edit: I'm not sure if the controls of card also includes groups, that may well be the case but may not be
Re: Cards controls loop?
Posted: Thu Aug 08, 2024 6:20 pm
by richmond62
The OP wants to find and collect ALL instances of a string in ALL objects that contain a script.
No, really?
When LiveCode introduced Unicode into the 'thing' I replaced thousands of occurrences of numToChar with numToCodePoint across about 50 cards in my 'eternally developing' Devawriter Pro using exactly what I suggested.
Re: Cards controls loop?
Posted: Thu Aug 08, 2024 6:30 pm
by dunbarx
Stam,
My bad. Groups are themselves another object class apart from their constituents (controls).
As I said I wrote this 15 years ago, taking from memory the same sort of tool from HC. I cannot now recall if I included HC backGrounds in that old handler. At that time groups seemed weird to me, and I avoided them.
Zax. So you would have to modify this handler using the properties Stam mentioned in its travels through every corner of your project. Anyway, the intent should be clear.
Craig
Re: Cards controls loop?
Posted: Fri Aug 09, 2024 6:45 am
by Zax
Thanks for your answers.
I didn't know the backgroundIDs property and it's helpful.
Though, looping through all controls isn't as easy as it seems... I'm working on it and keep you informed.
My goal is to retreive all objects - including substacks - of a given stack without duplicates. I'm currently expecting a list of objects' long IDs.
Re: Cards controls loop?
Posted: Fri Aug 09, 2024 7:54 am
by SWEdeAndy
Zax wrote: ↑Thu Aug 08, 2024 7:42 am
Of course, I could list the controls as I loop, and then test if the current control is already listed, but that seems a bit slow and crude. Is there a more elegant and faster way?
If it’s just one stack I’m not sure it would be perceptibly slow.
But one neat trick to not have to check for duplicates is to use an array. Iterate through all the controls (and yes, groups are also controls themselves, so they get included) and “put the long id of control i into myArray[the id of control i]”.
Disclaimer: I can’t test at the moment, being on vacation, but it should give some ideas…

Re: Cards controls loop?
Posted: Fri Aug 09, 2024 9:01 am
by Zax
SWEdeAndy wrote: ↑Fri Aug 09, 2024 7:54 am
But one neat trick to not have to check for duplicates is to use an array. Iterate through all the controls (and yes, groups are also controls themselves, so they get included) and “put the long id of control i into myArray[the id of control i]”.
Well, as
backgroundIDs and
groupIDs properties are in my case not very convenient to use (only the top-level groups are reported), I think I'll use your trick. Thanks

Re: Cards controls loop?
Posted: Fri Aug 09, 2024 9:12 am
by bn
Hi Zax,
Here is a stack that uses the array form to eliminate duplicates. I did not know the backgroundIDs either but this is not needed when using the array form.
The stack seems to work. It does not do Substacks of stacks.
Maybe it gives you some ideas.
Kind regards
Bernd
Re: Cards controls loop?
Posted: Fri Aug 09, 2024 9:22 am
by Zax
Thanks Bernd!
With all your answers, I'm planning to write a function to list all controls - including stack and substacks - that I'll use to:
- search strings in scripts (with the number of found occurences)
- store controls size and position (used to restore controls size and position after a voluntary or involuntary resize - stupid accidents sometimes happen during development - of a stack)
Re: Cards controls loop?
Posted: Fri Aug 09, 2024 2:38 pm
by bn
Hi Zax,
here is a version of "SearchScriptsBN" that searches also all sub stacks of a stack.
Some cleanup of code.
A technical note: I use "controlIDs" of cards. Unfortunately "controlIDs" are not documented in the dictionary. They return the ids of all controls of a card, i.e. also the ids of controls within groups and controls of groups in groups.
"ChildControlIDs" return only controls on the card and the top group id as id and do not go further down into the group etc.
Please note that in the result field if there are more than one hit then clicking on the number will open the script at that number. Otherwise clicking on a result line will open the script at the first line number reported.
Kind regards
Bernd