Humanities Home page   Office of Digital Humanities
Back     BYU LiveCode Lessons Gateway

Computers & the Humanities 210

Labeled Picture Task

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 InClass/LabeledPicture folder on the DigHT 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.

Creating Highlights

First we will be creating graphics that will highlight the parts of the image that we will be labeling later on.

  1. Identify 8 – 10 things in the image that you want to label. For example, stove, microwave, refrigerator, bar, stool, window, cupboard, sink.
  2. Use the graphic tool Freehand Polygon to draw an outline around each of these objects.
      Make sure that:
    • the polygon is opaque;
    • the ending point of the polygon is exactly the same as the starting point, so that it is completely closed off.
  3. Give each graphic the name of the thing it is outlining; for example, graphic "stove", graphic "window", etc.
  4. Set the line color and the fill color of the graphic to something nice and bright, like red, that stands out clearly against the image.
  5. The first graphic object, around the stove, is already done as an example.

  6. Now write a handler that will make each outline on the image "light up" when the mouse cursor moves over it, and "turn off" again when the mouse cursor moves away from it. To do this you need to find:
  7. Once you have this working for one of the graphics, copy and paste your handlers into 2 or 3 others to see if they work there, too.
      Did you remember that referring to me when setting the blendLevel property is a quick way of acting on the object that holds the handler?
  8. 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.

  9. Copy your handlers into the card script, and delete them from the graphic objects. There is one change you will have to make now that the handlers are not in the objects they are acting on: me will no longer work; you'll have to refer to the target instead.
  10. 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.

  11. Edit the mouseEnter and mouseLeave handlers in the card script and make this change: put the set the blendLevel command inside an if structure, like this:
    if the name of the target contains "graphic" then
      set the blendLevel of the target to 100 -- (or 60)
    end if
    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.)

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.

Adding the Labels

  1. Create a transparent, borderless field for the stove label, and give it the name "stove". Type the word "stove" in the field, and lock its text. Set the text font, size and color to settings that stand out well against the image.
  2. Make a copy of this field for each of the other items you chose to highlight in the image. Change the text in the field and set the name of each field to match the name of the corresponding, highlighting graphic object.
  3. In the "stove" graphic write a handler that will show the label field "stove" when you click on the graphic object.
  4. In the "stove" field write a handler that will hide field "stove" when the mouse is clicked—you can decide whether you want to hide the field on mouseUp or mouseDown.
      Eventually you'll want a similar handler for each field. How can you write the handler so that all you would have to do would be to copy and paste it into each field's script? Right again! Try 'hide me'.
  5. Now copy and paste this handler into the script of every field.... Wait! We've been down this road before. This is not an efficient way to do this. Instead, paste the handlers in an object higher up the message hierarchy--the card would be a good choice again.
      Remember to change me to the target when moving this handler to the card script.
  6. 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:

  7. Now you have some unfinished business from step three. So far only one graphic object has a handler in it to make its label field appear. You need to give all the graphics that capability. Now you are thinking, "I already know it's a Bad Idea™ to copy and paste the same handler into all of the graphics. I'll move this handler up the message hierarchy." A good place to put it would be where you have put all the other handlers.

    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".

  8. There is one more task left to finish this phase of the activity. You have to make the 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
    end if

Making it Better

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:

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   
  end if
end repeat
(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.)

Another Way

Let's make one more copy of card one, at the end of the stack:

  1. Make sure you are on the last card of the stack.
  2. Do this in the message box:
    copy card 1 to this stack

    Now you should have an exact copy of card 1 at the end of the stack.

  3. Change the text in the title field to say something like "Variation 2".

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.)

  1. Find a beginning-level language textbook to use as a source. The textbook may be for either college or high school level. You may also look for language learning web sites as a source.
  2. Locate a simple picture in that book and scan it (or draw one of your own). You may also be able to find a suitable image on the internet. Wherever you get the image, remember to give credit to the source in your stack.
  3. Create a stack and name it YourName-LabelPict. Also give the stack an appropriate title (based on the language with which you are working). Place the picture on the first card of the stack.
  4. Identify objects in the picture by creating fields to label each part (at least 10 labels).
  5. Make each of those objects "hot" or clickable through some means so that the corresponding field/label is shown appropriately.
  6. As always, remember to observe LiveCode best practices.
  7. Put a copy of your finished stack in the Assignment Drop folder by the date indicated on the schedule.
These notes present one method to create a labeled picture activity for language learning. Hopefully one principle you learned from this exercise is that there is always room for improvement. Also, since what has been presented here does not pretend to be the most effective or efficient method, you are free to improve upon it. This was designed mainly to get you started with the creative process. Use your creativity to expand upon the information given and build something extraordinary.
Back     BYU LiveCode Lessons Gateway
Maintained by Devin Asay.
Copyright © 2005 Brigham Young University