Genevieve Young <[EMAIL PROTECTED]> wrote:
> Let me try to understand what I have learnt:
>
> a getPropertyDescriptionList is written in this way:
>
> 1. I first specify the properties I wish to change:
>
> in this case it was the position of the marker - property pMarker.
>
>
> I can specify as many properties I wish to change here, I just make sure I
> call for it in the event handlers like on mouseUp, on enterSprite, later
> within this script?
? You don't need to "call" for properties. You "declare" them at the top
of your script, then use them as needed in any of your handlers.
?? There is no #enterSprite event. You may be thinking of #mouseEnter or
#beginSprite.
> 2. then I create the on getPropertyDescriptionList
> specifying under what condition the behavior should work.
>
> 3. then I return the property
> with the #comment,#format and #default.
>
> Is this the correct format to write the handler?
Hi Genevieve,
Let's start with some pseudo-definitions:
handler: A recipe. Some recipes require you to use other recipes. The
recipe for lasagne will ask you to use the recipe for a white
sauce.
property: A bowl you can put some ingredient in so that you can find it
later. You can mix ingredients together or reuse the bowl, but
it's often cleaner to keep ingredients separate.
event: Instruction received from the chef or a another cook to use
a recipe
arguments: Ingredients handed over at the same time as the instruction, for
use in the recipe.
Some handlers modify properties, others return information, others again
affect the way things appear on the screen or on the hard disk.
When creating a behavior, you have two types of property: author-defined
parameters and internally-used properties. When making a pizza, you can
consider the ingredients for the topping to be author-defined and the
ingredients for the dough to be internal.
You also have two types of handler: author-time and run-time. Handlers such
as getPropertyDescriptionList(), isOKToAttach(), getBehaviorTooltip() and
getBehaviorDescription() do not normally get called at run-time. You can
safely strip these behaviors from a COPY of your movie before you convert it
to Shockwave, in order to reduce the file size. You can also remove any
other handlers that are called only from these event handlers.
Other handlers such as beginSprite(), mouseUp() and so on are called when
the movie is running.
The getPropertyDescriptionList() handler provides a menu for diners. The
diner does not need to know what the cooks actually do in the kitchen. When
you write behaviors for yourself, you are both cook and diner, but you tidy
the kitchen table before you sit down to eat.
When I cook up a behavior, I might work as follows:
1. Create a new script
2. Give the script an evocative name
3. Type a brief description of what the script is intended to do as a
comment at the top of the script
4. Write the getPropertyDescriptionList() handler. I write this as follows,
so that I can copy and paste property description chunks, then modify
the pasted chunk to define a new property:
First pass...
on getPropertyDescriptionList(me)
tPropertyList = [:]
return tPropertyList
end getPropertyDescriptionList
... to which I add chunks like this...
tPropertyList[ \
#customName] = [ \
#comment: <some explanatory string>, \
#format: <symbol>, \
#default: <default value> \
]
... so the finished handler may look like this:
on getPropertyDescriptionList(me)
tPropertyList = [:]
tPropertyList[ \
#markerName] = [ \
#comment: "On mouseUp, go to marker:", \
#format: #marker, \
#default: #next \
]
tPropertyList[ \
#jumpMode] = [ \
#comment: "Jump mode:", \
#format: #string, \
#range: ["Go to", "Play and Return"], \
#default: "Go to" \
]
return tPropertyList
end getPropertyDescriptionList
Note that you can provide an optional #range list of values, so that the
user can only make a limited number of choices.
Built-in Director behaviors use property names which have no "p" or "my"
prepended to them. This means that when you display the scriptList for
a sprite, the meaning of the properties is explicit:
put sprite(1).scriptList
-- [[(member 1 of castLib 1),"[#markerName: #next, #jumpMode: "Go to"]"]]
The getPropertyDescriptionList() handler is called at author-time only,
so I will include a comment to indicate this just before the handler.
Other author-time only handlers will be placed in the same section of the
script:
-- BEHAVIOR PARAMETERS AND DESCRIPTION --
on getPropertyDescriptionList(me)
-- etc
end getPropertyDescriptionList
5. Once I have decided what input is required from the author, I then
declare the properties used in the getPropertyDescriptionList() handler
at the top of the script:
property markerName
property jumpMode
<ASIDE>: This is not in fact essential. If you don't declare the
properties used in the getPDL handler, you can still access them by
using "me.propertyName". For example:
on beginSprite(me)
put #markerName, me.markerName
end
However, if you don't declare any properties, the cogs button in the
Property Inspector will not work.</ASIDE>
6. I now determine what events the behavior will need to deal, and create
an event handler for each such event. I try to keep event handlers as
short as possible, so that they explain what happens, but do not go into
any details:
on mouseUp(me)
me.mJumpToMarker()
end prepareFrame
7. After these preparations, I am ready to write the main bulk of the code.
I separate this off into a section called "Private Methods", to indicate
that the handlers in that section should never be called from anywhere
else. Director lets you call any handler anywhere at any time, so this
is merely a semantic distinction. I include a description of the action
of each handler at the start:
-- PRIVATE METHOD --
on me.mJumpToMarker(me) ---------------------------------------------
-- SENT BY: mouseUp()
-- ACTION: Jumps the playback head to the chosen marker... if it
-- still exists
-------------------------------------------------------------------
-- Determine which frame is indicated by markerName
case markerName of
#previous: tFrameNumber = marker(-1)
#loop: tFrameNumber = marker(0)
#next: tFrameNumber = marker(1)
otherwise:
tFrameNumber = marker(markerName)
end case
if tFrameNumber then
if jumpMode = "Go to" then
go tFrameNumber
else -- play => play done
play tFrameNumber
end if
else
-- markerName no longer exists
end if
end me.mJumpToMarker
8. More complex behaviors may also include a "Public Methods" section which
includes so-called Accessor and Mutator methods: handlers which allow
a different script to access information inside the behavior, or to
change the value of the behavior's properties. These handlers are often
written "defensively" so that a call made using the wrong syntax will not
cause any problems:
-- PRIVATE METHOD --
on mSetJumpMode(me, aJumpMode) --------------------------------------
-- Mutator method
-- ACTION: Modifies jumpMode if <aJumpMode> is a recognized value
-------------------------------------------------------------------
case aJumpMode of
"Go to", "Play and Return": jumpMode = aJumpMode
otherwise: -- ignore the call since the value not recognized
end case
end mSetJumpMode
9. Finally, I add isOKToAttach, getBehaviorTooltip() and
getBehaviorDescription() handlers to describe the way the behavior works.
If I am particularly pleased with my behavior and graphically inspired, I
may also create a thumbnail icon for the behavior so I can recognize it
easily in my Cast Lib of custom behaviors.
10. Should I have mentioned testing early, testing often and testing on all
target platforms somewhere?
Cheers,
James
[To remove yourself from this list, or to change to digest mode, go to
http://www.penworks.com/lingo-l.cgi To post messages to the list,
email [EMAIL PROTECTED] (Problems, email [EMAIL PROTECTED])
Lingo-L is for learning and helping with programming Lingo. Thanks!]