In almost any given beginning-level language book, you find several pictures that have been labeled in the target language: a picture of a room, a drawing of a person, an image of a specific object, etc. Such pictures are designed to introduce vocabulary words in context. Through judicious application of the various techniques we have acquired in using LiveCode, we can create a similar activity to introduce vocabulary to a new language learner. With computer technology, however, we can make the picture a little more interactive. Just as a text can be hyperlinked to provide supplementary information and instruction, so can a picture.
Download the stack called "LabeledPicture.rev" from the Templates folder on the CHum 210 server. This will be the template for this activity. Look at the first (and so far only) card. It contains a single background group. Note which objects the group contains.
First we will be creating graphics that will highlight the parts of the image that we will be labeling later on.
The first graphic object, around the stove, is already done as an example.
blendLevelproperty to 100 when you want to hide the highlight and to around 60 when you want to show it.
Now stop and think: Isn't it inefficient to copy and paste identical scripts into several similar types of objects? How can we remedy this? Right! By moving the handlers up the message hierarchy, so they can act on several objects.
Do you notice some unanticipated, undesired behavior? Notice what happens when you move the mouse in and out of the various other objects on the card. How can you prevent the blendLevel from changing on these other objects, effectively causing them to disappear?
Somehow you need to limit the mouseEnter and mouseLeave handlers to only acting on the graphic objects and not on everything else. Remember the property the name from the reading? In the message box type
put the name of graphic "stove" and hit return. Note that the name of an object contains both the type of object and the name of the object. In this case, 'graphic "stove"'. That means you can tell what kind of object the target is by checking its name property.
set the blendLevelcommand inside an if structure, like this:
Apply the script and try it again. The script should now only work on the graphics. (You may have to take a minute and fix the blending level of the other objects that were affected by the former handlers. Remember that the blendLevel of the card may also have been affected, so check the card's Blending setting in the property inspector first.)if the name of the target contains "graphic" then set the blendLevel of the target to 100 -- (or 60) end if
Now you should have a really nice highlighting effect for all of the outlined items in the image. It's time to take the next step.
Again, you will notice that this mouseUp handler will affect every object on the card--even the ones you don't want to hide when clicked!
Use the technique from #7 and 8 in the previous section to limit the mouseUp so that it only affects the label fields. This time, you'll need to also figure out a way to prevent the title, source, and counter fields from being hidden. Here's a suggestion:
if the name of the target contains "field" then hide the target end if
on mouseUp -- nothing here, but it blocks the message! end mouseUp
But there is a problem: there is already a mouseUp handler in the card script. How can you make this handler do one thing for fields and another thing for graphics? The key lies, again, in the name property. See if you can modify the existing if structure to do something different if the name of the target contains "graphic".
show field "stove"command that you moved from the stove graphic more general so it works for all of the graphics. What you need to do is write the command so that it does this (in pseudocode):
show the field that has the same name as the graphic being clicked
The key to this lies in the short name property. If you enter in the message box
put the short name of graphic "stove"
You get the result
So in your mouseUp handler in the card script, if you put the short name of the target graphic into a variable, then show the field that has the name contained in the variable, your code will work for all the graphics. Try it before you peek back here for the solution.
Here's how you would do this, added to what you did before:
if the name of the target contains "field" then
hide the target
else if the name of the target contains "graphic" then
put the short name of the target into thingName
show field thingName
Now you have a fully functioning labeled picture activity. But there are things you could do that would make it even better. First let's duplicate this card. Instead of simply making a new card, we want to make an exact copy of it so we can modify it without destroying the work you've already done. Do this in the message box:
copy this card to this stack
Now card 2 is an exact copy of card 1. Change the text in the title field to "Reset Button".
Despite the wisdom of the adage that "if it ain't broke, don't fix it," there is still room for improvement with this labeled picture. As presently designed, the stack requires the user to click each field to make it disappear. This can be quite annoying, particularly if there are numerous items we've labeled. The picture rapidly becomes cluttered with labels. We need a quick way to hide all fields without having to click on each one. Let's create a reset button. We could script it to hide each field by name, but this would require us to write a hide statement for each labeled item. Obviously this is too much work (remember that it is laziness—errr—efficiency that pointed us in this direction in the first place). We need a way to cycle through the fields and hide each one.
A repeat loop with an incrementing variable would work splendidly. Also by using the number of fields within the control structure for the repeat loop, this will hide exactly the number of existing fields: No more, no less. With a handler written this way, we could add/delete fields and not have the need to alter the handler. It will always cycle through the number of existing fields and hide each one from the first until the last. This gives the user a greater level of control over the learning environment.
However, in solving one "problem" we immediately create three or four new problems. Scripting it this way will hide all fields, including information fields we have on the card to label the card, give credit, etc. Since we don't want that to happen, we need to somehow find a way for LiveCode to differentiate between fields that need to stay and fields that need to be hidden. One solution is to only hide the fields for which there is also a graphic with the same name, like this:
(Using the get command and the variable it is simply a quick way of grabbing a value—the short name of a field, in this case—and storing it in the special variable it. It would work just as well to put the short name of the field into some other variable and use that variable instead.)
repeat with fldNum = 1 to the number of fields
get the short name of field fldNum -- (remember the get command?)
if there is a graphic it then --(get uses the special variable it)
hide field fldNum
Let's make one more copy of card one, at the end of the stack:
copy card 1 to this stack
Now you should have an exact copy of card 1 at the end of the stack.
Once again, we don't need to be completely satisfied with our present design, as there is always a better way to do it. Currently the exercise is based entirely on the mouseUp message: The user clicks to see a word and then clicks to hide that word. We could take advantage of the other messages being sent and incorporate them in such a way as to improve the design of our stack.
First, let's think about using the mouseDown message in conjunction with the mouseUp. These are reciprocal messages that complement each other nicely for this type of activity. One could place two message handlers in the card script: One to show the label, and one to hide it. This design would create an environment where holding the mouse down over a particular item will display its label. Letting the mouse go up will then hide the label. This effectively displays the label as long as the mouse is down. Remember to account for all message possibilities. This would be a slick and clean design which renders the reset button obsolete (i.e., the activity cleanup is not user-dependent).
Another possibility is to use the mouseEnter and mouseLeave messages. These two messages—like mouseDown and mouseUp—are also complementary and can be used effectively together. So two message handlers on the card script could cause the corresponding words to appear when the user passes the cursor over each highlight graphic in the picture. Upon exiting the graphic, the corresponding field is then hidden. As with the mouseDown-mouseUp design, this design has no need for a reset button. The user leaves the activity in the same condition in which it was found, so it is always ready for the next user.
As always, look for a Key stack that shows suggested solutions in the Keys folder on the server.
Your assignment, then, is to create a labeled picture exercise/activity of your own—don't just turn in this stack. (If you want your final project to have an activity like this in it, you might want to consider using this assignment as a "building block" for your project, and use textual material that relates to your project topic.)