Cards controls loop?

LiveCode is the premier environment for creating multi-platform solutions for all major operating systems - Windows, Mac OS X, Linux, the Web, Server environments and Mobile platforms. Brand new to LiveCode? Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Zax
Posts: 519
Joined: Mon May 28, 2007 10:12 am
Contact:

Cards controls loop?

Post by Zax » Thu Aug 08, 2024 7:42 am

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?

stam
Posts: 3060
Joined: Sun Jun 04, 2006 9:39 pm

Re: Cards controls loop?

Post by stam » Thu Aug 08, 2024 10:00 am

I think backgrounds are not contained within cards - that's the point of them.
you could use

Code: Select all

get the backgroundIDs of <stack>

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:
Full default LC message paths.jpg
Regards
Stam

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10305
Joined: Wed May 06, 2009 2:28 pm

Re: Cards controls loop?

Post by dunbarx » Thu Aug 08, 2024 2:11 pm

"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
Last edited by dunbarx on Thu Aug 08, 2024 3:50 pm, edited 2 times in total.

richmond62
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 10076
Joined: Fri Feb 19, 2010 10:17 am

Re: Cards controls loop?

Post by richmond62 » Thu Aug 08, 2024 3:02 pm

I would like to search for all occurrences of a string in all scripts of a stack.
-
FandR.png
-
I tend to use the built-in Find and Replace stack.

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10305
Joined: Wed May 06, 2009 2:28 pm

Re: Cards controls loop?

Post by dunbarx » Thu Aug 08, 2024 3:47 pm

Richmond.

The OP wants to find and collect ALL instances of a string in ALL objects that contain a script.

Craig

stam
Posts: 3060
Joined: Sun Jun 04, 2006 9:39 pm

Re: Cards controls loop?

Post by stam » Thu Aug 08, 2024 5:09 pm

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

Code: Select all

get the backgroundIDs of <stack>
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.

stam
Posts: 3060
Joined: Sun Jun 04, 2006 9:39 pm

Re: Cards controls loop?

Post by stam » Thu Aug 08, 2024 5:19 pm

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

richmond62
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 10076
Joined: Fri Feb 19, 2010 10:17 am

Re: Cards controls loop?

Post by richmond62 » Thu Aug 08, 2024 6:20 pm

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.
Last edited by richmond62 on Thu Aug 08, 2024 6:41 pm, edited 1 time in total.

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10305
Joined: Wed May 06, 2009 2:28 pm

Re: Cards controls loop?

Post by dunbarx » Thu Aug 08, 2024 6:30 pm

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

Zax
Posts: 519
Joined: Mon May 28, 2007 10:12 am
Contact:

Re: Cards controls loop?

Post by Zax » Fri Aug 09, 2024 6:45 am

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.

SWEdeAndy
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 324
Joined: Sat Aug 16, 2008 9:48 am
Contact:

Re: Cards controls loop?

Post by SWEdeAndy » Fri Aug 09, 2024 7:54 am

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… :)
Andreas Bergendal
Independent app and system developer
Free LC dev tools: https://github.com/wheninspace
(WIS_WebDeployHelper, WIS_ScriptDependencies, WIS_BrowserAnimation)
WhenInSpace: https://wheninspace.com

Zax
Posts: 519
Joined: Mon May 28, 2007 10:12 am
Contact:

Re: Cards controls loop?

Post by Zax » Fri Aug 09, 2024 9:01 am

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 :)

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4163
Joined: Sun Jan 07, 2007 9:12 pm

Re: Cards controls loop?

Post by bn » Fri Aug 09, 2024 9:12 am

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
Attachments
searchScriptsBN.livecode.zip
(2.7 KiB) Downloaded 315 times

Zax
Posts: 519
Joined: Mon May 28, 2007 10:12 am
Contact:

Re: Cards controls loop?

Post by Zax » Fri Aug 09, 2024 9:22 am

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)

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4163
Joined: Sun Jan 07, 2007 9:12 pm

Re: Cards controls loop?

Post by bn » Fri Aug 09, 2024 2:38 pm

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
Attachments
searchScripts_02_BN 2.livecode.zip
(2.78 KiB) Downloaded 362 times

Post Reply