Decals and Decal Sheets
The main feature of the framework is the DecalSheet system (located in the camo.core.decal package); made up of the DecalSheetManager, DecalSheet and Decal classes. The DecalSheet concept was inspired by the decals you would get with model airplanes. Each model kit would contain sheets of graphics and on each sheet you could peal off a decal and place it on the model. Camo’s version of the DecalSheet allow you to load in external images, cut out decals, and skin your application with the Decals. The following diagram will help when explaining the relationship between the three classes:
DecalSheetManager
The DecalSheetManager (located in the camo.core.managers package) is the manager for the decal system. It handles the xml that defines a list of DecalSheet images and coordinates for cutting out each Decal. It also stores a collection of DecalSheets to make createing complex Decal look up tables easier to manage. You can configure DecalSheets and Decals on the DecalSheetManager at run time or with XML. Once this data is set, the DecalSheetManager goes out and gets all the images it needs for the DecalSheet images. Lets look at how to configure a DecalSheetManager with XML:
Sample DecalSheet XML
The above DecalSheet XML is broken up into two main nodes, one for Sheets (DecalSheets) and the other for Decals. Each Sheet node contains an name (unique reference name), preload (true or false), w (width) and h (height) attributes along with the src representing the path to file. You can add as many sheets as your application requires. Remember to only flag the critical ones for preloading to cut down on load time. The decals node defines how each decal should be cut out. A decal node has an name (unique name for lookups), sheet (name of the DecalSheet where Decal will be cut out from 1), x, y, w, and h.
To use this XML, simply call the DecalSheetManager’s parseXML method. Once xml is parsed, the DecalSheet requests a list of all the sheet nodes flagged to be preloaded and begins loading the src images. The baseURL attribute, located in the sheets node, is added to the url of each page’s src when making the load request. You can leave this empty and point each src directly to an absolute url if your images are not located in the same directory.
The DecalSheetManager makes use of a special loader class called the BitmapLoaderManager (located in the camo.core.managers package). Once the images are loaded, the DecalSheetManager is ready to be used. If a page is not flagged to be preloaded but is requested, it will be added to the load queue. Decals can still be requested before the DecalSheet images are fully loaded. The DecalSheetManager will use a Decal’s width and hight to generate a proxy graphic (a temporary black placeholder graphic) that will be replaced once the corresponding DecalSheet has been loaded. The DecalSheetManager also makes use of the LoaderManagerEvent to dispatch updates on preload and regular loading progress. You can listen for preload next (LoaderManagerEvent.PRELOAD_NEXT), preload done (LoaderManagerEvent.PRELOAD_DONE), and load complete (LoaderManagerEvent.COMPLETE). You can use this to display load status as well as monitor the progress of preloading/loading of DecalSheet source images.
DecalSheet
Loaded images get stored inside of a Dictionary within the DecalSheetManager as individual DecalSheets. Each sheet’s key come from its name. At any time you can get a Sheet by calling getSheet on the DecalSheetManager. The DecalSheet uses the sample method for cutting out BitmapData from its source. When you request a sample, you must pass it a name that refers to a Rectangle defining the x, y, width, and height of the area to cut out. DecalSheets can be configured at run time without XML since a DecalSheet extends the Bitmap Class. Simply pass it a bitmap to use as the source image and use registerDecal on the DecalSheet to configure it at run time. Using a DecalSheetManager simplifies the process but DecalSheets and Decals can be used on their own whenever needed. Here is a diagram to illustrate the process:
Decal
A Decal is a Bitmap that contains a reference to the DecalSheet it was cut out from. Now that you have seen how we get xml data into the DecalSheetManager, lets talk about how to retrieve Decal instances. When you call getDecal on the DecalSheetManager or DecalSheet, you need to supply the name of a Decal. You can check if a Decal exists by looking through a DecalSheet’s decalName Array. Once a Decal is requested, the Decal’s name gets passed to the parent DecalSheet through the sample method and the Decal’s BitmapData is returned inside of a new Decal Instance.
Since all Decals contain a reference to the DecalSheet it was cut out from, this connection allows the Decal to receive updates from its parent DecalSheet. You can change a DecalSheet’s BitmapData at any time just as you would any other Bitamp instance. Decals listen for Event.CHANGE events from their parent Sheet and once an event is received, it resamples the DecalSheet and updates its own BitmapData 2. Imagine being able to reskin an entire application by changing the BitmapData in a single DecalSheet? Here is a diagram to illustrate how this works:

Changing the BitmapData of a DecalSheet will fire a CHANGE event telling all children Decals to update.