two somewhat related questions

Got a LiveCode personal license? Are you a beginner, hobbyist or educator that's new to LiveCode? This forum is the place to go for help getting started. Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller

Post Reply
marksmithhfx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 931
Joined: Thu Nov 13, 2008 6:48 am

two somewhat related questions

Post by marksmithhfx » Wed Sep 14, 2011 3:39 am

Hi everyone, I have two questions, somewhat related, I hope someone can help with.

1. If I have a field x that has a handler that calls a popup menu with the command

popup btn "my popup menu"

is there anyway for the popup menu (button) to know which field initiated the popup operation (put another way, to know which field 'called' the popup menu)?

2. if both objects, the field and the button, are in the same group, is there anyway from script for each object to know the name of the group that contains them? And, is it possible for the two objects to share "group" custom properties?

Thanks a bunch,

-- Mark
macOS 12.6.5 (Monterey), Xcode 14.2, LC 10.0.0, iOS 15.6.1
Targets: Mac, iOS

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

Re: two somewhat related questions

Post by dunbarx » Wed Sep 14, 2011 5:18 am

1- Doesn't the field that invokes the handler know who it is? I am being flip; maybe I do not understand the question.

2- Check out the "owner" in the dictionary.

What properties did you have in mind? In a sense, grouped objects already are sharing certain "properties", for example radio buttons have a grouped attribute that permits one of many to be hilited. But fields and buttons, say, still retain their own object-specific ones. Do you mean share a script, as if the behavior (look up "behavior") of each object was set to effect that functionality?

Craig Newman

marksmithhfx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 931
Joined: Thu Nov 13, 2008 6:48 am

Re: two somewhat related questions

Post by marksmithhfx » Wed Sep 14, 2011 3:36 pm

dunbarx wrote:1- Doesn't the field that invokes the handler know who it is? I am being flip; maybe I do not understand the question.
Hi Craig, perfectly legitimate question. Consider the situation where a popup menu performs some functions on the field (add, edit, delete). You can "hard code" the name of the field into the popup menu code, but then it needs to be rewritten for every field that uses the popup. Better if you could "pass the name" of the field to the popup and then have it operate on that information... makes it more generic (actually, this is a whole area I've decided to try and get a handle on in LC which is how do you write generic code). So, for example, if the popup option was "delete" and the mouse is placed over a particular word, phrase or item in a field (or list field) then currently I have code that is written as:

case "Delete"
put the cselectedline of fld "Scrolling List Field" into x -- the line number
put line x of fld "Scrolling List Field" into temp
put "Delete" && temp && "from field Scrolling List Field?" into tprompt
answer warning tprompt with "Yes" or "No"
if it is "Yes" then
delete line x of fld "Scrolling List Field"
end if
break

And you'll recognize that cselectedline is custom property in the scrolling list field that identifies which line the user was selecting to delete. In this case we are using a custom property of the field to id the line which works fine.... IF you know the field name. You can't "pass" the field name in the same way using a custom property. And, to be completely generic, the calling field should not stuff the field name into a custom property of the pop-up menu button, because to do that would require hard coding the button name into the field script... hardly generic code.

What ideally I want to write is something like:

case "Delete"
put the cselectedline of fld gfieldname into x -- the line number
put line x of fld gfieldname into temp
put "Delete" && temp && "from" && gfieldname && "?" into tprompt
answer warning tprompt with "Yes" or "No"
if it is "Yes" then
delete line x of fld gfieldname
end if
break

So that the code can operate on any field that calls it. And, as you can see, I am currently doing that using a global variable gfieldname. Now, the downside to a global variable, of course, is that both the calling field and the popup menu have to know about the global variable and each needs to initialize it. Hardly generic. But, you've provide the perfect solution which is the answer to my second question... I had gotten as far as thinking that there probably was a way for these two objects to know about each other in LC if they were in the same group, but I could not figure out what the command (in this case property) was... and its:

2- Check out the "owner" in the dictionary.

Perfect. Now I can rewrite the code as:

case "Delete"
put the short owner of me into tgroup -- gets the group name (owner) of this menu
put the cfieldname of grp tgroup into tfieldname -- get the field name that called the menu (haven't tested this yet)
put the cselectedline of fld tfieldname into x -- the line number
put line x of fld tfieldname into temp
put "Delete" && temp && "from" && tfieldname && "?" into tprompt
answer warning tprompt with "Yes" or "No"
if it is "Yes" then
delete line x of fld tfieldname
end if
break

Now the field and the popup can interact and neither needs to know the name of the other. Put another way, if you place this group on a card you can call the field and the popup menu anything you like and the code will still work fine.

Or so the theory goes :-) I haven't tested any of this yet so I am hoping it works!!!
dunbarx wrote:What properties did you have in mind?
In this case the properties would be the information that the pop-up needs to operate on: the field name and the item in the field. Currently I call the popup like this:

if theButton is 3 then -- right button
-- set a custom property of this field to word 2 of the selectedline
-- and set the gfieldname to the name of this field
-- the last two are needed by the "Popup" menu
set the cselectedline of me to theline
put the short name of me into gfieldname -- for passing to the popup menu (using global var)
popup button "Popup Menu"

Now I'll be able to change that so the field name is a custom property of the group (I think?)

put the short owner of me into tgroup
set the cfieldname of grp tgroup to the short name of me -- instead of a global variable
popup button "Popup Menu"

and get it at the other end (the menu end) using the code I wrote above. I'm just writing this as I prepare to rush off to work but I get the general idea (and will worry about the syntax later).
dunbarx wrote:Do you mean share a script, as if the behavior (look up "behavior") of each object was set to effect that functionality?
I haven't looked into behaviours but will take a look as well. Thanks Craig for your many suggestions. I think the "owner" property is the key,

Cheers,

-- Mark
macOS 12.6.5 (Monterey), Xcode 14.2, LC 10.0.0, iOS 15.6.1
Targets: Mac, iOS

marksmithhfx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 931
Joined: Thu Nov 13, 2008 6:48 am

Re: two somewhat related questions

Post by marksmithhfx » Thu Sep 15, 2011 2:17 am

Hi Craig, so back home from work and time to fiddle....

I put a scrolling list field and popup button into a group. I put the following code into the scrolling list field handler

local popupname = "popup menu"

on mousedown
put the short name of the owner of me into tgroup
set the cfieldname of grp tgroup to the short name of me -- should create a custom property with the name of the current field
set the cselectedline of me to "2" -- another custom property, this time simulating saving a line selection
popup btn popupname
end mousedown

and in the popup menu I put...

on menuPick pItemName
switch pItemName
case "choice 1"
put the short name of the owner of me into tgroup -- what group do I belong to?
put the cfieldname of grp tgroup into x -- get the fieldname
put x into msg -- display it
put return & the cselectedline of fld x after msg -- show the selected line number
break
end switch
end menuPick

And it all worked. To test the generic-ness of the code, I changed the field name and the popup menu name and the only code I had to modify was in initializing the local var popupname in the field. In the popup menu nothing had to change at all.

And it all worked great, so thank you....

-- Mark
macOS 12.6.5 (Monterey), Xcode 14.2, LC 10.0.0, iOS 15.6.1
Targets: Mac, iOS

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

Re: two somewhat related questions

Post by dunbarx » Thu Sep 15, 2011 5:27 am

Glad to hear all is well.

Is it so that a "mouseDown" handler in the field calls the popup? You do know about the "target", of course.

Craig Newman

marksmithhfx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 931
Joined: Thu Nov 13, 2008 6:48 am

Re: two somewhat related questions

Post by marksmithhfx » Thu Sep 15, 2011 5:42 am

dunbarx wrote:Glad to hear all is well.

Is it so that a "mouseDown" handler in the field calls the popup? You do know about the "target", of course.

Craig Newman
That easy huh? I hadn't used "the target" before so when I read about it I don't think I saw the connection, but yes... now it is obvious.

Post edit: but when I tried it it did not work. Dragged a field (lock text) and a popup onto a new card. In the field put "on mousedown/popup btn "popup menu"/end mousedown" and in the button put "case "Choice 1"/put the target/break"

and the result of clicking in the field and selecting Choice 1 resulted in button "PopUp Menu" being displayed as the target not field "whatever name" being displayed, which is what I would need. Which is odd, don't you think?

-- Mark
macOS 12.6.5 (Monterey), Xcode 14.2, LC 10.0.0, iOS 15.6.1
Targets: Mac, iOS

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

Re: two somewhat related questions

Post by dunbarx » Thu Sep 15, 2011 4:37 pm

The target is the object that first received the message. This is implemented as a function, and might change if subsequent messages are sent to other objects, as I think you are doing.

Perhaps the mouseDown handler can, very early on (like right after "on mouseDown") save the target in a custom property or something that you can retrieve later?

Just so you have done it, run a mouseUp handler in a button:

on mouseUp
put the target
end mouseUp

This is a very powerful tool.

Now check out "target" in the dictionary as a keyword instead of a function.

Craig Newman

marksmithhfx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 931
Joined: Thu Nov 13, 2008 6:48 am

Re: two somewhat related questions

Post by marksmithhfx » Sun Sep 18, 2011 2:32 am

dunbarx wrote:The target is the object that first received the message. This is implemented as a function, and might change if subsequent messages are sent to other objects, as I think you are doing.

Perhaps the mouseDown handler can, very early on (like right after "on mouseDown") save the target in a custom property or something that you can retrieve later?
Hi Craig, that is basically what I am doing....

put the short name of the owner of me into tgroup -- what group do I belong to?
set the cfieldname of grp tgroup to the short name of me -- create a custom property with the name of the current field
popup button popupname

and then on the popup end of things....

put the short name of the owner of me into tgroup -- what group do I belong to?
put the cfieldname of grp tgroup into tfieldname -- get the fieldname

dunbarx wrote:Just so you have done it, run a mouseUp handler in a button:

on mouseUp
put the target
end mouseUp

This is a very powerful tool.

Now check out "target" in the dictionary as a keyword instead of a function.
Yes, you're right... that will come in handy in lots of places. I also received another suggestion in email that works well and I thought I would share it with the forum.... basically send a dispatch command to the popup button to setup the fieldname as a custom property...

on mousedown
dispatch "setup_popup" to btn "popup menu" with the short name of me
end mousedown

and then in the setup code have it execute the popup using "popup me" at the end, like this....

on setup_popup pfieldname
-- put the fieldname into a custom property
set the cfieldname of me to pfieldname
popup me
end setup_popup

on menuPick pItemName
switch pItemName
case "choice 1"
put the cfieldname of me
break
end switch
end menuPick

I've tested this and it works. It also has the advantage that I don't need to use a group as an intermediate mechanism to communicate the field name to the button (although for a completely separate reason the group thing has an advantage in my case). So, I could do it either way. Long story short, going back to my original question (which I'm sure we have all forgotten by now) as to whether it was possible for the popup button to know which field invoked it, I have at least two good ways to do that now (use a group or use dispatch) so many thanks for all of the helpful suggestions and comments that were generated here.

Cheers,

-- Mark
macOS 12.6.5 (Monterey), Xcode 14.2, LC 10.0.0, iOS 15.6.1
Targets: Mac, iOS

Post Reply