Using Images in DropTool Stacks

Since the key feature of the DropTools Palette is automating the copying of resources and libraries to the user's stack, it becomes very important to understand what is going on and how LiveCode handles the copying of images.

Normally, when you drag and drop a DropTool onto a stack, the DropTool Palette will copy over any objects that are inside a group object on the DropTool stack named "<dropToolType> Resources". These resources may include image objects that need to be used, such as those that make up the visual part of your custom control. You may also have one or more images inside the custom control group itself that will end up getting copied to the target stack as well.

This is an example from the stsProgBar DropTool:

image_ex3

The object inside the red box is the "stsProgBar Resources" group, and contains images for both Mac and Windows implementations of the indeterminate progress bar.

How LiveCode Avoids Image ID Conflicts

LiveCode tries very hard to avoid having two images with the same ID numbers in existence at the same time:

  • It will prevent you from assigning an ID to an image if an image with that ID is already in use.
  • If you import a new image, it will automatically assign it the next "unused" ID number.
  • If you copy and image from one stack to another (either manually or by script), it will automatically apply a new ID to the new copy of the image.

The last item in the list is particularly important, since this is exactly what the DropTools Palette needs to do after a drag and drop.

So imagine, if you will, a button and an image on a card of a stack:

image_ex1

The button shows the icon clearly because it's "icon" property is set to the same ID as the image.

Now if you copy both those objects to the clipboard, close (and even purge from memory) the first stack, create a new one and paste, you get this:

image_ex1
The image was
automatically renumbered
to 1003, and thus the button, which is still looking for an image with an ID of 10000 to use for the icon, can't find it and therefore no icon is displayed.

As you can see, unless something special is done, referenced images inside the DropTool instance could point to nowhere or to the wrong image.

How Does the DropTools Palette Handle This?

In order to deal with this situation, the DropTools Palette performs the following tasks when image resources need to be copied for this first time (the first drop of this DropTool onto the user's stack):

  1. It looks through all the objects, looking for image objects, and associates the ordinal number of that image with its ID before it is copied
  2. It looks for any buttons that are to be copied, notes down all of the icons (and icon variants) that are in use and what IDs they were connected to
  3. It then copies over all of the images and retrieves their new IDs
  4. It then copies over any buttons that need to be copied, and sets their icons (and icon variants) to the new IDs.

Then, the next time a DropTool control of the same type is added to the stack, it just uses the new IDs of the images that were already copied.

Won't This Affect My DropTool Scripts?

It might, depending on how you reference images in your scripts. One thing that can help mitigate this is to use
names
instead of numbers, along with a consistent, unique naming convention. LiveCode will let you use image names to assign icons to buttons and embed images in fields (imagesource), and it will search for an image of that name and use the ID of that image when it assigns the image to the button or field.
Note that in the case of working with icons, using names only works for
setting
icons, but not for
getting
them.

Here's a few example of script changes that will make your life easier:

Avoiding Image Reference Issues

Instead of This... Do This...
-- Depends on IDs that might change


on mouseUp
  if the icon of me is 10000 then
    set the icon of me to 10001
  else
    set the icon of me to 10000
  end if
end mouseUp
-- Don't depend on IDs, initialize with a 
-- custom prop and then check that

on mouseUp
  if the uIconShowing of me is "NoCheckMark" then
    set the icon of me to "Checkmark"
  else
    set the icon of me to "NoCheckMark"
  end if
end mouseUp
set the imageSource of \
  char 1 of fld 1 to 10001
set the imageSource of \
  char 1 of fld 1 to "infographic"
The nice thing about this is that if you get the htmlText of the field, the name sticks with it:
put the htmlText of fld 1
Returns:
<p><img src="infographic"></p>

Is Image Name Resolution Used Universally?

Unfortunately, the answer is "no". As far as I know, only images used in icons and imageSource can be set by name; the following items can only be set by ID number:

  • The cursor
  • The dragImage
  • All patterns (backgroundPattern, foregroundPattern, etc.)

There is an open request to RunRev to expand the use of images to allow for name referencing throughout the entirety of the LiveCode language filed at the RunRev Quality Control Center. If you feel like adding your two cents to that request, feel free to do so!

 
© 2015 Sons of Thunder Software, Inc.