Events sent from card to "behave like background" groups

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

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
lexogram
Posts: 13
Joined: Fri Oct 17, 2014 6:58 pm

Events sent from card to "behave like background" groups

Post by lexogram » Mon Oct 20, 2014 5:13 pm

Hi LiveCoders!

I have an issue with mouse events leaking through from one group and triggering handlers in a different group.

In the LiveCode dictionary for `backgroundBehavior` I read:
The group's script is placed behind the card in the message path for any message not originating from a control within it.
It seems therefore that the following behaviour is expected. This is what happens:

I want to group a set of controls together, and have a group script handle the mouse actions with the controls within the group. I want this group to appear on more than one card. I want to have more than one group of this kind. I want each group to mind its own business.

However, when I create two groups and place them on two cards, a click on an object in one group sends mouse events to the other group.

I can prevent this by placing dummy mouse event handlers in each object, or on each card. I can also create a switch case in the group script, to ensure that only the controls that are expected to be in that group react to the mouse events that are detected.

All of these workarounds requires hard-coding or placing dummy handlers in inconvenient places. It is an anathema to encapsulation.

What are the LiveCode best practices for dealing with this situation?

EDIT: Here is one solution which must be used in every "on whatever" handler in the group script:

Code: Select all

on handlerName
   get the target
   repeat while it is not me
      get the owner of it
      if it is empty then
         exit mouseUp
      end if
   end repeat

  -- Code that only applies to controls in this group
end handlerName
Feature suggestion: perhaps groups with their `backgroundBehavior` property set to true could have a `protectedScript` property; when this is set to true, it would ensure that event handlers in the group script are only triggered if the event was generated within the group itself.

Thanks in advance for your insights,

James
Last edited by lexogram on Mon Oct 20, 2014 6:45 pm, edited 1 time in total.

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

Re: Events sent from card to "behave like background" groups

Post by dunbarx » Mon Oct 20, 2014 6:43 pm

Hi.

The behavior is correct. But help me see your point.

If you have two groups, all set up as you said, then any click on any object in that group will execute the script of that object. If you click on blank space in that group, or on the card itself, then the group script with the lowest layer will fire, simply as a matter of LC protocol.

But I never see what you describe, that another group executes its script. Make two named bg groups, each with two named buttons. In the script of each button:

Code: Select all

answer the short name of me
In each group script:

Code: Select all

on mouseup
  answer the short name of me && the short name of the target
end mouseup
Click on a button. Click anywhere. Can you say where your gadgets differ from mine?

Craig Newman

lexogram
Posts: 13
Joined: Fri Oct 17, 2014 6:58 pm

Re: Events sent from card to "behave like background" groups

Post by lexogram » Mon Oct 20, 2014 7:22 pm

Hi Craig,

You are right. If both group scripts have a handler for a given event then the event will be handled by that handler. However if one group script does not have that handler, then the event is forwarded to the card, and then to the group in the highest layer that has a handler for it.

Here are my steps.

1. Create a new stack
2. Add a new button. Call it Button 1.
3. Select this button and use Object > Group Selected to create a new group. Call it Group 1.
4. Check the "Behave like a background" checkbox in the Inspector.
5. Repeat steps 2 to 4 twice, to create Button2/Group 2 and Button 3/Group 3
6. For Group 2 and Group 3, create a script:

Code: Select all

on mouseUp
   answer the short name of the target && the short name of me
end mouseUp
7. Create a new card
8. In the Project Browser, for card 2, swap the layers of Group 2 and Group 3, so that Group 2 is in the highest layer.
9. Click on Button 1 or on the card. (Neither of these have a mouseUp handler)

Results: On card 1, you will see an answer dialog that says "Button 1 Group 3". On card 2, you will see "Button 1 Group 2". This is the anomaly that I am describing. Group 1 is the lowest level of background. If I understand correctly, the order of event handling should be:

the target > (its owner groups >) the card > background group 3 > background group 2 > background group 1 > stack

In this case, an event starting in the lowest background group is then executed in a group at a higher level. Is this the intended behaviour?

If you click on the card (rather than on any button), you will see an answer dialog that says "Card 100X Group Y", (where X and Y may vary), indicating that the group in the highest layer has intercepted the event, as a background. I understand that this is how the "Behave like a background" feature is intended to work: the background is the next deepest layer after the card.

On both cards, if you click on Button 2 or Button 3, you will see an answer dialog where the Button number and the Group number match. This is normal, since the event is handled inside the group and is never forwarded to the card or beyond.

Does this help you to reproduce the issue?

James

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

Re: Events sent from card to "behave like background" groups

Post by dunbarx » Mon Oct 20, 2014 10:33 pm

Well.

It appears that the background layer has its own hierarchal pecking order, and that is the higher layer control receives messages first. This can be demonstrated by placing a "pass mouseUp" in the upper layer control, and then the handler in the next layer DOWN will fire.

This is counterintuitive to me. On the card layer, the first control to get a message is the lowest one. Always has been. If you have three ordinary buttons all named "button", and all with:

Code: Select all

on mouseUp
answer the number of me
end mouseUp
and you:

Code: Select all

send "mouseUp" to btn "button"
The lower button returns a value. On the background layer, the order is reversed:

btn 1 -- click here
btn 2
btn3 --this button's script gets the message

It is as if these groups are separate "backgrounds", as if they live in their own "subLayer" world between the card and the stack layers, and not merely controls on the "backGround" layer. It is the only way I can make sense of it.

But if you create three new buttons, set their background behavior to "true" and place a "mouseUp" handler in each that shows which one has received a message, the order is ordinary, with the lowest one firing when you "send mouseUp to btn "button".

Anyone want to chime in?

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10052
Joined: Sat Apr 08, 2006 7:05 am
Contact:

Re: Events sent from card to "behave like background" groups

Post by FourthWorld » Tue Oct 21, 2014 12:13 am

dunbarx wrote:It appears that the background layer has its own hierarchal pecking order, and that is the higher layer control receives messages first. This can be demonstrated by placing a "pass mouseUp" in the upper layer control, and then the handler in the next layer DOWN will fire.

This is counterintuitive to me.
To a lot of people, but it was the way HyperCard worked so when LiveCode added backgroundBehavior they added it in a way that maintains compatibility with the older ways of doing things.

However, a few versions back they got around to fixing it: you can now set the sharedBehavior of a group to true, and like backgroundBehavior it will be shared across any cards the group is placed on, but unlike backgroundBehavior it doesn't come after the card in the message path, but instead is immediately after any controls within it.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

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

Re: Events sent from card to "behave like background" groups

Post by dunbarx » Tue Oct 21, 2014 12:56 am

Richard.

Thanks. I think this came up a while ago, and I simply forgot it.

Craig

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7393
Joined: Sat Apr 08, 2006 8:31 pm
Contact:

Re: Events sent from card to "behave like background" groups

Post by jacque » Tue Oct 21, 2014 4:53 pm

I don't think it could be how HC worked, since that only allowed a single background per card. In LC it may be that backgrounds receive messages in the reverse order they were added, like backscripts do.

For the OP, the most common way to handle ownership checks is:

Code: Select all

if the owner of the target is not me then pass myHandler
Or just use shared card groups as Richard suggested.
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

Post Reply