Use of layers in groups of groups - some observations

Anything beyond the basics in using the LiveCode language. Share your handlers, functions and magic here.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
Simon Knight
Posts: 845
Joined: Wed Nov 04, 2009 11:41 am
Location: Gunthorpe, North Lincs, UK

Use of layers in groups of groups - some observations

Post by Simon Knight » Sat Jun 16, 2018 11:17 am

Hi,
I have been trying to understand how Livecode uses layers especially with groups of groups. My app' has a group of seven objects used to describe an image. It uses one of these objects named "polaroid-n" for every image in a folder. There are five images in the folder so there are five polaroid group controls. These five group controls are themselves part of a single group on the card named PhotoViewer. I hope that this is all clear!

The user may drag the polaroids within photoviewer using the grab control and the group scrolls as required. When doing a grab and drag the selected polaroid is hidden by other polaroids with a higher layer number as expected. So I have been attempting to move the selected polaroid to the top layer to keep it in view but there have been problems.

The main problem is that while it is simple to change the layer number it is also very simple to remove the polaroid object from the group by setting a value higher than the groups upper limit. Worse changing the layer back to its original value does not always work as some components of the polaroid group get left behind, orphaned from their parents. ( Note this may have been through my lack of understanding)

I am new to changing layer values so I am probably messing things up but it seems that layers are a little more complex than they first seem. First layer values get changed by LC as controls are added and removed from the card, LC honours the layer order and thats all. Creating a group will change the layer values of controls outside the group as well as those inside the group. This makes sense as LC does not allow unused layer values and a group is based on the layer values of the controls inside it. Or to put it another way a group is just a named range of layer values.

While all of the above seems straight forward things are less clear when these controls are viewed in the IDE's object inspector. In fact it is all quite confusing.

In my application the object inspector shows that the layer of the large group PhotoViewer to be 3. If I select "edit group" and then I select the first polaroid it is shown as layer 2. In terms of the objects on the card this is wrong as the card already has an object with a layer of 2. The real, true, layer value of the polaroid group is 5 and may be found by looking at the plugin revApplicationOverview. Also it may be calculated by adding the two values together e.g. 3 + 2 = 5. Next if I choose to edit the child group polaroid1 then again the components are displayed with incorrect layer values of 1-7 . Again these are not "correct" with the true layer being determined by adding the layer steps i.e. 3+2+1=6 with six being the control numbered 1 in the object inspector. The bottom line is not to rely on the object inspector and use the plugin revApplicationOverview when viewing the layer values of objects

If you are still with me you may remember that at time the polaroid being dragged gets hidden by objects it is being dragged past. The user expects a dragged object to be in front while being dragged. When the layer number is set to a very high value Livecode sets the control to the next highest value in its list and the control will become the front control. However, at this point the control is no longer a member of the group and the group will have adjusted its self reallocating all the layer numbers. When the drag is complete it is necessary to add the control back into the group. This is where the fun begins.

In order to add a control to a group I tried to set its layer value to one that is inside the range of layers of the group. But to do this I had to also use the command RelayerGroupedControls to true. This is the catch as it is global and applies to ALL groups. Thus adding my polaroid group to a group of other groups adds my polaroid to a level. If previously that level was part of a child group then the object I am adding is added to the child and confusion is highly likely. If the main group is only child groups then the objects added this way will always be added to a child group. The only method I have discovered is to have a non group control such as a field in the main group and set my polaroid to the layer level of that field. Doing this ensures that the polaroid control is added to the main group and not a child. However, it is clumsy.

A better method is to use the copy command as it allows LC to do the layer number accounting. I tried this code, before it is executed Polaroid2 is outside the group PhotoViewer:

Code: Select all

on mouseUp pMouseButton
   copy group "Polaroid2" of this card to group "PhotoViewer" of this card
   set the name of it to "Polaroid2-1"
   Delete group "Polaroid2" of this card 
end mouseUp
Your comments and suggestions welcomed. Thanks for reading.
best wishes
Skids

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7210
Joined: Sat Apr 08, 2006 8:31 pm
Location: Minneapolis MN
Contact:

Re: Use of layers in groups of groups - some observations

Post by jacque » Sun Jun 17, 2018 12:20 am

When you edit a group, LC creates a temporary card in memory and copies the controls to it. That's why the layering changes; those controls are the only ones on the "card". If you refresh the app overview, it will show the same altered layering order during editing. (Right-click anywhere in the right-hand pane and choose "refresh" from the contextual menu.)

When you stop editing, the control changes are applied to the original group's controls and the temporary card is deleted. So, the layering during editing is a transient condition that only indicates the relative ordering of the controls in the group.

If you want a control to be topmost inside a group, get the number of controls of the group and add that to the layer number of the group itself.

Code: Select all

set the relayerGroupedControls to true
set the layer of btn "someBtn" to (the layer of grp "test" + the number of controls of grp "test"
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

SparkOut
Posts: 2834
Joined: Sun Sep 23, 2007 4:58 pm

Re: Use of layers in groups of groups - some observations

Post by SparkOut » Sun Jun 17, 2018 12:31 am

"relayer" is also a very useful, and possibly more convenient way to manage things these days.

You can

Code: Select all

relayer button "someButton" to front of the owner of button "someButton"
assuming someButton is in the group "someGroup" (ie someGroup is the owner of someButton and there isn't more nesting) then it will be the topmost control in group "someGroup". But you can specify all sorts of other ways to refer to the referential object and where to put it in relation.

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7210
Joined: Sat Apr 08, 2006 8:31 pm
Location: Minneapolis MN
Contact:

Re: Use of layers in groups of groups - some observations

Post by jacque » Sun Jun 17, 2018 12:35 am

I forgot all about "relayer". Good call.
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

Simon Knight
Posts: 845
Joined: Wed Nov 04, 2009 11:41 am
Location: Gunthorpe, North Lincs, UK

Re: Use of layers in groups of groups - some observations

Post by Simon Knight » Sun Jun 17, 2018 8:32 am

Hi Both,

Unfortunately the code

Code: Select all

set the relayerGroupedControls to true
set the layer of btn "someBtn" to (the layer of grp "test" + the number of controls of grp "test"
does not work as expected/wanted. The command relayergroupedcontrols is global meaning that all grouped controls are open for relayering. In my example I have a group of groups. Each child group comprises seven controls. The problem is that the number of controls will return the last control in the group which will be the last layer in a child control. So adding a control or group to this layer number will add it to the child group. As I say the only way to add to a group of groups is to have a non group control e.g. a field in the top level and then add the new components to the field's layer value. As I say above its a little clumsy.

I have not tried the relayer command but suspect that it will run into similar problems as the parent group just sees a whole load of child controls and ignores that they are inside groups.

If the relayerGroupedControls was group specific and not global then it might have worked.
best wishes
Skids

SparkOut
Posts: 2834
Joined: Sun Sep 23, 2007 4:58 pm

Re: Use of layers in groups of groups - some observations

Post by SparkOut » Sun Jun 17, 2018 8:40 am

For nested groups with relayer, this is where "the owner of" comes in handy.

Simon Knight
Posts: 845
Joined: Wed Nov 04, 2009 11:41 am
Location: Gunthorpe, North Lincs, UK

Re: Use of layers in groups of groups - some observations

Post by Simon Knight » Sun Jun 17, 2018 11:38 am

I have attached a small zipped stack file that demonstrates the issues with changing the layer values. To use first create a folder of six jpeg images. Now load the stack and select the button "Add Images" located in the bottom right of card. Navigate to your folder of images and select it. You should now see a list of thumbnails appear down the left side of the card. The large object with the scroll bars is group "photviewer". Each image is displayed in a child group each named Polaroidx. You should be able to scroll the images and drag drop them into new positions.

The large button "Set the layer of polaroid No2" sets the child group to the value entered into the field. the default is 100.

The large white field is field "debug" and displays the layers of the controls in the main group "photoviewer".

1. Press the button "report layers in group" - note that all six are listed with values along with the field.
2. Change the layer of polaroid 2 to 100 by pressing the Set.... button. This changes the layer and moves the location of polaroid2. Note do not select polaroid 2 as the code will crash out as the main group is no longer in the message path and this is a demo.
3. Now try and get polaroid 2 back into the group. This may only be achieved by setting its level to the level of the field thats in the group. All other values will add it to a child of the group or to the card. Note that part of polaroid 2 will be clipped when it gets added back to the main group and it will also be listed in the report.

enjoy!
Attachments
CustomControlBasedImageSorterv01.livecode.zip
Playing with a group of groups
(7.13 KiB) Downloaded 188 times
best wishes
Skids

Simon Knight
Posts: 845
Joined: Wed Nov 04, 2009 11:41 am
Location: Gunthorpe, North Lincs, UK

Re: Use of layers in groups of groups - some observations

Post by Simon Knight » Sun Jun 17, 2018 12:12 pm

Sparkout - great tip : adding the line

Code: Select all

relayer me to front of owner
in the child's mouse down achieves the aim of bringing the selected object to the front of the parent group.

I would not have discovered this from the dictionary as I have no idea what this means (was it written by the pythons)?
When using "front" the owner of the control becomes the owner of the target and is inserted after the last child of the target (only valid if target is a container). When using "back" the owner of the control becomes the owner of the target and is inserted before the first child of the target (only valid if target is a container).
The simple mouse down :

Code: Select all

On Mousedown
   grab me
   relayer me to front of owner
end Mousedown
Thanks.
best wishes
Skids

SparkOut
Posts: 2834
Joined: Sun Sep 23, 2007 4:58 pm

Re: Use of layers in groups of groups - some observations

Post by SparkOut » Sun Jun 17, 2018 12:43 pm

I was just playing with your stack and actually on my system (Windows 10, LC 9) the grabbed photogroup has a nice semi-transparency that is not obscured by any of the other groups while being dragged!

But anyway, I checked and yes, rather than relayer to a specific number over the top and outside the parent group, relayer to front works well.

I would get into the habit of using "the owner of me" or specific object reference though, LC tries hard to identify objects by implicit reference but with many layers of groups it could easily be confused.

Syntax-wise, for the same reason I would get used to distinguishing property references and variables by the use of "the" for properties, for instance

Code: Select all

put height of image "RowSnapShot" into tHeight
set topLeft of img "RowSnapShot" to pmouseX, pmouseY-(tHeight/2)

Simon Knight
Posts: 845
Joined: Wed Nov 04, 2009 11:41 am
Location: Gunthorpe, North Lincs, UK

Re: Use of layers in groups of groups - some observations

Post by Simon Knight » Sun Jun 17, 2018 4:51 pm

I stole the transparency code from a stack that Scott Rossi published some years ago. It takes a few lines of code to create the screen shot to drag but it gets around the front object problem by not moving anything other than the image. Using the grab option is simpler now that you have shown me the relayer command which may be used to force the grabbed object to the front of the group. One side effect that I have yet to overcome is that it resizes the parent group although I suspect that all I have to do is call my resize handler.

With ref to syntax I will make a note to be as explicit as I can. By the use of "the" do you mean that the example lines are better entered as :

Code: Select all

put the height of image "RowSnapShot" into tHeight
set the topLeft of img "RowSnapShot" to pmouseX, pmouseY-(tHeight/2)
or even

Code: Select all

put the height of image "RowSnapShot" of this card into tHeight
set topLeft of img "RowSnapShot" of this card to pmouseX, (pmouseY-(tHeight/2))
In mitigation I should say that this stack is all thanks to Craig who asked the question why was I using a datagrid when it was not necessary. So I have spent the past weeks seeing what I can come up with as an alternative UI and I have been a little free and easy with syntax and comments.
best wishes
Skids

Klaus
Posts: 13793
Joined: Sat Apr 08, 2006 8:41 am
Location: Germany
Contact:

Re: Use of layers in groups of groups - some observations

Post by Klaus » Sun Jun 17, 2018 5:34 pm

Hi Simon,

no need for "of this card" because that is the first place the engine presumes if you leave this out.

But I would stick to "THE height..." etc., the enigne is less forgiving with every new release and at some point it may actually DEMAND correct syntax.

Maybe I'm overcautious, but what the egg! :-)


Best

Klaus

SparkOut
Posts: 2834
Joined: Sun Sep 23, 2007 4:58 pm

Re: Use of layers in groups of groups - some observations

Post by SparkOut » Sun Jun 17, 2018 6:14 pm

What Klausimausi said. Also it is just more readable, every Livecoder will find it much more familiar to read "the property" versus getting a value from "tVariable".

Post Reply

Return to “Talking LiveCode”