mouseUp handler:
-- sprite script for some field called "wotsit" on mouseUp -- find out the number of the word that was clicked put the mouseWord into wordNum -- discover what that word actually is put word wordNum of field "wotsit" into clickedWord -- act appropriately if clickedWord = "blah" then go to "info about blah" end mouseUp
As well as the mouseWord, Director provides some other
functions to determine what part of a field the mouse is over:
the mouseChar the mouseItem the mouseLine
All of these return the *number* of their respective chunk in the field
that the mouse is over (if it is over a field). If you wish to discover
what that chunk contains, you have to get it from the field much as the
mouseUp handler above does. (It is quicker not to, however.
Putting the actual words in the script will make things clearer, but for
optimum performance you may want to use the numbers directly.)
These functions need not be used in response to a click. You may, for example, want to hilite the item under the mouse as the user moves it around by putting something like this in your idle script:
-- very basic handler to hilite any item under the mouse -- NB: a useable version would probably also unhilite items -- when the mouse leaves the field on idle put the mouseItem into theItem put the mouseCast into theField if theItem>0 and theField>0 then hilite item theItem of field theField end idle
Note that if the mouse is not over a text field, or is over some inappropriate
part of it like the border or scroll bars these functions return
-1 (that's what the if statement is for in the
above handler), but if the mouse is over empty space beyond the last chunk
in the field, the functions return the number of thelast chunk.
mouseWord function only picks up individual words,
delimited by spaces. In order to gather several words together into a
single hypertext link, you need to
separate them with characters other than a space.
On the Macintosh, a hard-space character can be inserted by pressing option-space (in some fonts this may look different to a normal space). In Windows (*******). The hard-space looks just like a space, but Director interprets it as a non-space and yokes together the words on either side into a single "word":
put "one two three" into blah -- this ^ is a hard space put word 1 of blah -- "one two"
You can however compare such a "word" to a phrase containing ordinary spaces and it will still match:
put word 1 of blah = "one two" -- this uses an ordinary space -- 1
Adjacent words may also be combined by using any other non-space character as a separator. This character can be disguised by setting it to the background colour of the field, though it will still show up with certain ink effects.
Text can be fully kerned, tracked, coloured and transformed using a dedicated graphics application such as Adobe Illustrator, then rasterized, anti-aliased and further manipulated in something like Adobe Photoshop to be imported into Director as a pict. This will result in much more attractive and often more legible text at the expense of editability and larger file sizes.
For text that does not need to be modified - or that you specifically *don't* want users to be able to edit, this can be a useful method. If your text must be alterable on the fly, however, you'll have to put up with less satisfactory typography.
Director does provide an option for anti-aliasing text. The level of anti- aliasing is set for specific sprites via the score. The "Anti-alias text & graphics" checkbox in the Movie Info dialog must also be checked for this to take effect.
The text anti-aliasing is pretty dreadful, though. The purpose should be to improve the appearance and readability of the text, but Director's just makes it look like you've left your contacts out. On the other hand, its anti-aliasing of graphics is *much* worse...
set the text of cast blah = empty
use:
set the text of cast blah = " " -- there's a space in here
set the textStyle of word 1 of cast 20 to "bold" set the textSize of char 10 of field "bingoBangoBongo" = 18 set the textFont of char 1 to 5 of cast "hello" = "Helvetica" set the foreColor of item 1 to 6 of field 12 to 128
The textHeight and textAlign properties can't be set for chunks. A command such as:
set the textHeight of line 17 of cast 90 to 28
will be accepted, but the textHeight will be applied to the
whole field
regardless.
Attempting to set the textAlign of a chunk results in a script
error.
However, these methods do not seem to be 100% reliable, so use them at your own risk.
[Caveat: see section 1.8]
The most notable application to support copying of styled text is Apple's SimpleText. ResEdit's styl/TEXT resource editor also supports copy and paste of styled text. (**** any other examples? ****)
[I don't presently have the info to provide a Windows answer for this...]
OpenXLib or OpenResFile to allow your movie to
use them. Alternatively, you can provide the fonts separately and ask the
user to place them in their Extensions or Fonts folder before running your
movie.
[Windows **** ?]
In all cases, care must be taken over copyright issues. Both bitmap and outline fonts remain in the copyright of their creators. If you wish to include font files with your movie, you must negotiate the right to do so with the copyright owner.
There are three ways to circumvent this:
The appearance of the letters of a font is not copyright, only the font itself. If you convert text into a bitmap picture, the picture may be freely distributed. This also allows you to nicely anti-alias (that is, smooth out the jagged edges of) the letters, if your pict is at higher than 1-bit resolution. The downside, of course, is that the text ceases to be editable, and your file size and possibly memory requirements will increase.
rect
of cast property:
set the rect of cast "myTextField" = rect(leff, topp, rite, bot)
The effect of this will depend on the style of the field being resized, as follows:
| Field Style | Width | Height |
| Adjust to fit | rite - leff | whatever's needed to accommodate text |
| Scrolling | rite - leff | bot - topp, but no less than 31 (minimum scrollbar height) |
| Fixed | rite - leff | bot - topp |
| Limit to field size | rite - leff | bot - topp |
Only the width and height of the rect are significant, not the offsets to left and top, ie:
rect(0, 0, 100, 100) rect(100, 100, 200, 200)
will both give the same results.
[Note that the Lingo Dictionary insists that the rect of cast
cannot be set, and for DfW this is correct. Given the slightly odd way this
works, it seems to be an oversight rather than a real feature, so the
caveats in section 1.8 should
probably be borne in mind...]
put empty before line whichLine of field whichField
However, this will only scroll the line into view, it won't necessarily position the line where you want it. Suppose your field can hold 9 lines before scrolling, and you've put twenty lines of text in it. If it starts out with line 1 at the top, saying
put empty before line 6 of field thisField
will have no effect, since line 6 is already onscreen. If you're anxious to actually scroll a particular line to the top, you might do something like this:
-- this takes a sprite rather than a field in order to -- evaluate its height - doing this with the cast leads -- to grief on moveLineToTop whichLine, whichSprite -- determine the field number put the castNum of sprite whichSprite into whichField -- work out how many lines are visible put the textHeight of field whichField into txHt put the height of sprite whichSprite into Ht put Ht/txHt into lineOffset -- jump to the top of the field put empty before line 1 of field whichField -- and then jump down as many lines *after* the one we want as -- will fit within the scrolling field put empty before line (whichLine + lineOffset) of field whichField end moveLineToTop
However, this does produce a nasty flicker while you jump to the top of the field, so it's best done with the relevant sprite somewhere offstage or invisible.
on scrollUp fieldSprite -- in this case, let's assume we're using an actual live text -- field and scroll up by one line at a time -- get the line height first set theField = the castNum of sprite fieldSprite set myHeight = the textHeight of field theField -- move the sprite up one line set the locV of sprite fieldSprite = (the locV of sprite fieldSprite) - myHeight updateStage end scrollUp
(Obviously in this case the sprites must be puppeted for the changes to be persistent).
This sort of technique has the advantage that it can be used (less the
references
to the textHeight of field, that is) for bitmaps as well,
thereby avoiding the problems with antialiasing and cross-platform
differences discussed here and in
section 17. However, it does place constraints on screen layout, since you need
the masking sprite in front.
An alternative when using bitmaps would be to use the mask ink effect, and
provide a mask bitmap that can substitute for an onstage sprite. In order to do
this, you need to adjust the regPoint of the mask castmember,
while at the same time moving the sprite in the same direction (in effect
the mask provides a
window onto the text):
on scrollUpMask whichSpr, howFarUp -- scrolls a bitmap image of text within a masking "window" -- by a given number of pixels set textImage = the castNum of sprite whichSpr -- when scrolling up, the bitmap must move down, which means -- its regPoint must move up set the regPoint of cast (textImage + 1) = the regPoint of cast (textImage + 1) - point(0, howFarUp) -- adjust the sprite location accordingly set the locV of sprite whicSpr = the locV of sprite whichSpr - howFarUp updateStage end scrollUpMask
Finally, you could simply manipulate the contents of a live text field, so that its contents reflect a small visible portion of a larger actual field. If the display field is of fixed size, it can start off containing the whole text and you only need to delete or replace the first line to scroll the text within it (note that this only works right if there's a return character at the end of each line):
-- this sort of thing can be more easily maintained using objects, -- but let's assume a single source and destination and globals to -- hold everything -- note that we also need the sprite the destination -- field is displaying in, since we need to know its height in order to -- make sure we don't keep going past the end on scrollUpText global gSourceLine, gSourceField, gDestField -- check that we aren't at the top if gSourceLine <= 1 then return -- move the pointer up the source set gSourceLine = gSourceLine - 1 -- copy across the line above, to scroll upwards put line gSourceLine of field gSourceField & return before field gDestField end scrollUpText -- for completeness, here's a corresponding scrollDown script: on scrollDownText global gSourceLine, gSourceField, gDestField, gDestSprite -- check that we aren't at the bottom if gSourceLine > the number of lines in field gSourceField - (the height of sprite gDestSprite / the textHeight of field gDestField) then return -- delete the top line to get it to scroll downwards delete line 1 of field gDestField -- adjust the pointer set gSourceLine = gSourceLine + 1 end scrollDownText
(This isn't an exhaustive list of ways to do this, by any means, just a few examples.)
The only way I can see to avoid this is to create your own custom scrolling field script as in 9.10 above. (If someone has a better solution, let me know!)
Maricopa Center for Learning and Instruction (MCLI)
The Internet Connection at MCLI is
Alan Levine --}
Comments to
levine@maricopa.edu
URL: http://www.mcli.dist.maricopa.edu/director/faq/faq9.html