Target not working???

David Burgun dburgun at dsl.pipex.com
Thu Mar 30 08:23:01 EST 2006


Hi Rob,

On 28 Mar 2006, at 23:33, Rob Cozens wrote:

>
> Dave,
>> When I start a new app, I take whatever pieces I need from the  
>> Object Library or existing apps, throw them into a new app and the  
>> stuff that did work still works (with no or minimal changes to  
>> Custom Properties), leaving just the task that I really want to do  
>> which is design and code the new piece.
>
> OK, I'm beginning to conceptualize your library.  But C was almost  
> as incomprehensible to me as HyperTalk was to you; so sending  
> messages in C is pretty much foreign, or long-ago visited,  
> territory.  The part about building a GUI with objects from a  
> library seems straightforward.  But I still have no feeling for  
> what is involved in "visually updating" controls either via custom  
> properties or looping.  Is this necessary every time a stack that  
> includes an iteration of the control opens?
>
> From my limited perspective, I think of "visually updating" of a  
> control as involving manipulation of properties like colors/ 
> patterns, image/icon, or text formatting.  These don't seem to me  
> to be prime candidates for runtime updating, and if they were, I  
> would assume a consistent look & feel is desired throughout the  
> GUI...if so, colors & text can be changed en masse by setting them  
> to empty for all objects subordinate to the stack and making all  
> changes at the stack level.  Images can be changed by switching  
> image libraries or changing image files for referenced images.

By visually updating I mean doing anything to the control that needs  
to be done in order to either initialize it or update (actually one  
and the same using ISM) it in response to a external event, e.g. as  
the result of a user action or as the result of a timed action.

The type of "update" performed depends on the control itself and the  
type of command being processed. For instance a Regular Push Button  
might require the following update actions:

1,  Enable/Disable itself depending.
2.  Make itself visable/invisibilty.
3.  Change it's label text (say in response to a "change_language"  
message.

A field might want to all of the above or it might want to do some  
processing in order to generate the "update" value for the field   
(such as getting a file list from a folder or putting the contents of  
a file into itself).

An Image might want to rotate itself.

Since all the logic for how a control "updates" itself *may* (notice  
the word may!)  be placed in the object itself, copying it copies all  
that is necessary to perform the update. The code needn't be on the  
object itself. The only reason the update handler gets called in the  
object is because the object registered itself for the message(s) it  
requires in order to update correctly (this is why I want to loop  
through all the objects in a stack and call a ISM_InitializeObject  
handler, see below). Instead of registering at the control level, you  
could register at the Group or the Card or the Stack level For  
instance, if you decided to handle all "updates" for a Group Object  
in the Group Script, then the ISM_InitializeObject handler would be  
called from the Group Script and this handler would register itself  
as wanting to receive all the messages for the controls inside it. If  
you did it that way however, you'd have to use hard coded object  
names and refer to the them like so:

put "xxxxx" into field "FieldFolderPathName" of me

This would limit the scope to just that group. If you did it this way  
you sacrifice some flexibility, since now if you delete a control  
from the group and it was referred to in the Group Script you'd get  
an execution error or you'd have to make the Group Script more  
robust. e.g:

if exists( field "FieldFolderPathName" of me) then
      put "xxxxx" into field "FieldFolderPathName" of me
end if

Similarity,if you register at the card level, you'd have to access  
the controls in the card like so:

if exists( field "FieldFolderPathName" of "GroupFolderSelect" of  me)  
then
    put "xxxxx" into field "FieldFolderPathName" of  
"GroupFolderSelect" of  me:
end if

This loses more flexibility.

If you listen at the stack level, then the code would be:

if exists( field "FieldFolderPathName" of "GroupFolderSelect" of   
card "CardCompare" of me) then
    put "xxxxx" into field "FieldFolderPathName" of  
"GroupFolderSelect"  of  card "CardCompare" of  me
end if

Losing more flexibility.
>
>>> My impression is you a building a library of "standardized  
>>> objects" to be referenced by multiple stacks.  All iterations of  
>>> standardized objects in that stack are to be initialized per a  
>>> library stack handler when it opens and set to some other state  
>>> when the stack closes.  Is that essentially the goal of the example?
>>
>> Yes, that's it. In order to do the above, a "Listen" routine needs  
>> to be called for each object that wants to receive a message. The  
>> listen function can be called at anytime, but to make it easier to  
>> use, I am scanning for the ISM_InitializeObject handler and if  
>> it's present, call it. The ISM_InitializeObject in the target  
>> object can then call the Listen function to register itself (or  
>> any other object for that matter). The same goes in reverse, I  
>> want to stop listening when a stack closes.
>>
>
> In out-of-the-box Transcript, every object with a script is born  
> listening.  The trick is to place a handler in the spot in the  
> message hierarchy where it hears requests from all objects that  
> need its services.

Yes I can see this, that's really what I am trying to do, but I found  
no way of doing it using directly using the message hierarchy. Maybe  
I am missing something. How would you write code to do the following  
by placing the handler(s) in the spot in the message hierarchy where  
is hear requests from all objects that need its services?

Field:StaticText:"Folder Selected" (Needs to Change when the language  
is changed).
Field:Variable Text:<Currently Selected Folder Path Name> (Needs to  
change when user selects a Folder, must handle Drag and Drop of a  
folder onto it and Display the Folder Path Name).
Button:PushButton:Clear  (Needs to Change when the language is  
changed, needs to be enabled if a folder is selected and disabled if  
not, should clear Currently Selected Folder when pressed.)
Button:PushButton:Choose  (Needs to Change when the language is  
changed, should allow the user to select a folder and update  
Currently Selected Folder with the new folder and should enable the  
clear button)

The above controls represent that is necessary to "drive" a folder  
choosing group, if that's all the app needs to do, fine, but if you  
wanted to do something more with the folder, the fact that a folder  
has been selected by the user must be somehow transmitted to the  
"interested" fields. So there should be a mechanism to pass the  
folder selected to other controls in any of the cards in any stack  
that happens to be opened.
>
> So one can make handlers and images available to any stack by  
> placing the handlers in the library stack script and/or placing the  
> images on the first (or any?) library card.  One can change icons  
> en mass by switching between to image libraries containing images  
> with identical ids.  One can change images by referencing image  
> files instead of importing them and then changing the files in the  
> image folder.  One can change handler action by editing the handler  
> in the library.  One can change the colors and text format en masse  
> by maintaining inheritance in all objects below the stack level.   
> Combined, these techniques support making changes in one file or  
> folder that will be recognized at runtime by any stack that uses  
> any of the modified resources.
>
> Isn't that what you are trying to accomplish when you place a  
> generic control & it's associated script in the object library?

Yes, except that rather than passing the actual data just a token  
(messageID/messageKind/token) is passed, the token can is then used  
to decode the token in any way it chooses, like passing a file  
reference for images in your exampl).

ISM doesn't stop you from using any of the techniques above, I use a  
mixture of all those things in my ISM based apps.

Not sure if this makes it any easier, but if ISM were built into  
RunRev, then it could be implemented like this:

send "message_handler_name,messageID,messageKind,theToken " to all  
objects that are currently interested.

or at a lower level"

send "message_handler_name messageID,messageKind, theToken " to all  
objects whose messageIDProp = messageID and whose  messageKindProp =  
messageKind in messageTimeProp ticks

on message_handler_name messageID,messageKind theToken
end message_handler_name

Thanks for a lot for your input, if there is something I am missing  
in RunRev (xTalk) that is easier/faster than using ISM I'd be happy  
to change how I am doing things.

All the Best
Dave




More information about the use-livecode mailing list