CamoDisplay

Posted on August 6, 2009

The CamoDisplay is the final building block of the framework and a powerful alternative to the native Sprite class. Before getting into the CamoDisplay we should take some time to talk about the AbstractDisplay and the BoxModelDisplay.

AbstractDisplay

The AbstractDisplay handles the foundation for the BoxModel and CamoDisplay classes. Not only does it make public two methods, move and resize, but it also handles redraw and visual invalidation to optimize the graphic redraw for the display classes of the framework. The most important feature of the AbstractDisplay however is what happens when we call addChild and removeChild. The AbstractDisplay automatically creates a container called “display” that gets added as the first child to the display list. Every time another DisplayObject is added to an AbstractDisplay, it gets attached onto the class’s display instance. All the display list methods are mapped over to the internal display Sprite. Here is a chart to illustrate the inheritance of Camo’s display classes:

display_inheritance

BoxModelDisplay

The BoxModelDisplay allows us to apply Margin, Padding, Border and a Background (Color/Image). The BoxModelDisplay manages the offset of the display sprite based on those properties. Lets take a look at how the Box Model gets rendered:

box_model

Camo’s Box Model consists of a Margin, Border and Padding wrapped around a display.

Here is a list of supported properties of BoxModel:

CSS Property Values Example (px is stripped out by the parser)
background-alpha “number range 0 – 1″ Example: background-alpha: .8;
background-color valid hex color background-color: 0xff0000; sets background red.
background-color: #ff0000; sets background red.
background-image type filename
jpg, png, or gif
background-image: url (/imgs/sample_image.jpg); Will load in sample_image.jpg and redraw Box Model once loaded.
background-position value for x y background-position: 10px 30px; This only works if background-repeat is set to no-repeat.
background-repeat “repeat no-repeat repeat-x repeat-y” background-repeat: no-repeat; does not repeat the background image, can be used with background-position to move the image’s x,y position.
background-repeat: repeat-x: Repeats the background image along its x value based on the height of the background image.
background-scale9 value for
x, y, width, height
background-scale9: 1px 1px 98px 48px; applies a scale9Grid to the background image.
border

or

border-top

border-right

border-bottom

border-left
value for
size style color alpha
border: 1px solid #ff0000 .5; solid is the only style supported currently.
border-alpha “value range 0 – 1″ border-alpha: .5; height value height: 50px;
margin

or

margin-top

margin-right

margin-bottom

margin-left
value for
top, right, bottom, left
margin: 5px 2px 2px 5px; applies values to top, right, bottom,left
margin: 5px 2px; applies 5 to top & bottom, 2 to right & left
margin: 10px; applies 10 to top, right, bottom, left. **Margin is not rendered, you must check its value when performing layouts with BoxMode/CamoDisplays**
padding

or

padding-top

padding-right

padding-bottom

padding-left
value for
top, right, bottom, left
padding: 5px 2px 2px 5px; applies values to top, right, bottom,left
padding: 5px 2px; applies 5 to top & bottom, 2 to right & left
padding: 10px; applies 10 to top, right, bottom, left
width value width: 100px;

BoxModel Background

A BoxModelDisplay’s background-color and background-image work exactly to how it would in HTML. The background-color is the bottom most color behind the display. It is important to realize that the CSS width and height affect how the background fill will take place. If you do not define the width and height of the BoxModel, it will use the values from the display. The background-image gets composited on top of the background-color. The background-image property lets the box model know how to load in a source image 7. Background-images also have repeat rules: repeat (is default), no-repeat, repeat-x, repeat-y. When using no-repeat you can specify a background image’s position (x, y) to offset the image. This is helpful when you only want a background-image to be displayed at a certain location behind the display.

bg_repeat

When the BoxModelDisplay does a refresh 8, all of its values are reviewed and drawn to the graphic’s layer of the BoxModelDisplay. This insures that the border, background-color, and background-image are a single Bitmap to save on memory. The display Sprite (where all children get added to) is offset by the top and left Padding, and Border 9. Once the refresh is complete the display will be correctly positioned. Padding is invisible unless you have set a background color or image. In that case, the background will show through in the area offset by the padding. When you request the width or height of a BoxModelDisplay the dimensions are returned taking into account the padding, border and display. The BoxModelDisplay can be used on its own but when combined with the CamoDisplay, you get additional css style support.

CamoDisplay

The CamoDisplay inherits some powerful layout logic from the BoxModelDisplay and introduces the applyProperties method. By passing a PropertySelector (obtained from a CamoStyleSheet) the CamoDisplay will attempt to apply the PropertySelector’s values 10. This takes advantage of the PropertyApplierUtil and TypeHelperUtility that is part of the Property Managment System in Camo.

Here is a list of the properties supported by the CamoDisplay:

CSS Property Values Example (px is stripped out by the parser)
align “left (default) center right” align: left; the logic for this should be in another Class that extends the CamoDisplay or add’s the CamoDisplay to its display list.
alpha “value range 0 – 1″ alpha: .5; sets the alpha to 50%;
cursor “hand pointer none” cursor: pointer; this is a read only property. The actual logic to manage the cursor should be done in a class that extends the CamoDisplay.
overflow “visible(default) hidden” overflow: visible; any graphics outside of the display’s css width and height will be displayed.
overflow: hidden; the display is masked off based on the style’s width and height. If no width and height is set in the style the mask not work correctly.
rotation number value rotation:180; sets the rotation to 180.
scale9Grid “values for x y width height” scale9Grid: 1px 1px 98px 48px; applies a rectangle to the CamoDisplay’s scale9Grid property.
vertical-align “top (default) middle bottom” vertical-align: top; the logic for this should be in another Class that extends the CamoDisplay or adds the CamoDisplay to its display list.
visibility “visible(default) hidden” visibility: hidden; sets visible to false;
x number value x: 10px; sets the x position to 10;
y number value y: 10px; sets the y position to 10;
z-index number value z-index: 5; This is supported in the CamoDisplay addChild is called.

The most important functionality added by the CamoDisplay is the rasterize method. Just like the BoxModelDisplay which draws its border, background-color, and background-image to the graphics layer, the CamoDisplay can do the same thing with its display Sprite. When you call rasterize, a Bitmap snapshot of the display is take, the old display is removed and a new one is put in its place with the previous display’s BitmapData drawn to it’s graphics layer. All the children that were attached to the display are removed (so the Garbage Collector can release them from memory) and you are left with a flattened display.

It is important to note that rasterize can only be called only once since all children in the display are removed. The speed and memory benefits can greatly increase the performance of your application. This also allows you to layer images in the display Sprite and then flatten them into a single image. Rasterize should be used on any CamoDisplay where its children will never be changed or used outside of the initial setup of the class. It is also an excellent technique to use when animating text.

TypeHelperUtil

Although the TypeHelperUtil (located in the camo.core.utils) does not belong to any one system in Flash Camo, it is key in converting string values from a PropertySelector into correctly typed data to be applied to your Class. The TypeHelperUtil contains a lookup table of functions to handle conversions of specific data types. Primitives such as Number, Array, and Object are built in. This is used as part of the applyProperties method in the CamoDisplay in conjunction with the PropertyApplierUtil. By default the TypeHelperUtil supports the following conversions:

Built in Type Support

Function Name String Data Example Description
stringToArray one two three This will convert any string into an array by splitting the spaces. This is based on CSS rules. You can override the default delimiter by calling the function directly.
stringToBoolean true or false Converts any true or false into a Boolean.
stringToDictionary prop:value; prop2:value2;

Creates a Dictonary out of a string by splitting all elements by the semi-colen. The results are then split on the colon. Anything on the left of the colon becomes the property and the string to the right become the value.
stringToNumber 999 Converts any string into a number.
stringToObject prop:value; prop2:value2; Similar to how stringToDictonary work except the returned value is an Object.
stringToPoint 10 10 Creates a Point instance from a string using the space as a delimiter.
stringToRectangle 10 10 100 100 Creates a Rectangle instance from a string using the space as a delimiter.
stringToStyleSheet style1{color: #ffffff} Creates a StyleSheet from any string by taking advantage of the parseCSS method on Flash default StyleSheetClass.
stringToUint 0 or #000000 or 0×000000 or black This will convert any string into a uint. It is primarily used to converts colors into uints. Color shortcuts are supported as well as CSS Style hex values.
stringToUrlRequest url(‘path/to/anything’) Converts any string into a URLRequest. This method only uses the string inside of the url(”); Likewise you can leave the quotes out or use double quotes.

The TypeHelperUtil also supports color shortcuts when converting colors into uints. Here is a list of supported colors and their values:

Color Support

Color Preview Value Color Preview Value Color Preview Value
black  0×000000 olive  0×808000 purple  0×800080
blue  0×0000FF white  0xFFFFFF teal  0×008080
green  0×008000 yellow  0xFFFF00 fuchsia  0xFF00FF
gray  0×808080 maroon  0×800000 aqua  0×00FFFF
silver  0xC0C0C0 navy  0×000080 magenta  0xFF00FF
lime  0×00FF00 red  0xFF0000 cyan  0×00FFFF

In addition to the built in string conversion methods you can register your own. The TypeHelperUtil has two methods for extending the functionality of the utility called registerFunction and removeFunction. You can also customize and extend the built in color support through the registerColor and removeColor as well. This allows you to add your own conversion based on your projects needs.

If you want to add your conversion functions you need to use the class’s qualified name as the key. As an example to correctly convert a Point from a string, you would register your conversion function to flash.geom::point and not to a reference of the Point class itself. It is recommended that you register all custom functions in your doc class before you application gets started. If you are dynamically adding conversion functions that are specific to a particular section you should remove all unused function since they will not allow the Garbage Collector to remove your classes properly.

Comments are closed.


PHVsPjxsaT48c3Ryb25nPndvb19hZGRibG9nPC9zdHJvbmc+IC0gZmFsc2U8L2xpPjxsaT48c3Ryb25nPndvb19hZHNfcm90YXRlPC9zdHJvbmc+IC0gdHJ1ZTwvbGk+PGxpPjxzdHJvbmc+d29vX2FkX2ltYWdlXzE8L3N0cm9uZz4gLSBodHRwOi8vd3d3Lndvb3RoZW1lcy5jb20vYWRzL3dvb3RoZW1lcy0xMjV4MTI1LTEuZ2lmPC9saT48bGk+PHN0cm9uZz53b29fYWRfaW1hZ2VfMjwvc3Ryb25nPiAtIGh0dHA6Ly93d3cud29vdGhlbWVzLmNvbS9hZHMvd29vdGhlbWVzLTEyNXgxMjUtMi5naWY8L2xpPjxsaT48c3Ryb25nPndvb19hZF9pbWFnZV8zPC9zdHJvbmc+IC0gaHR0cDovL3d3dy53b290aGVtZXMuY29tL2Fkcy93b290aGVtZXMtMTI1eDEyNS0zLmdpZjwvbGk+PGxpPjxzdHJvbmc+d29vX2FkX2ltYWdlXzQ8L3N0cm9uZz4gLSBodHRwOi8vd3d3Lndvb3RoZW1lcy5jb20vYWRzL3dvb3RoZW1lcy0xMjV4MTI1LTQuZ2lmPC9saT48bGk+PHN0cm9uZz53b29fYWRfdXJsXzE8L3N0cm9uZz4gLSBodHRwOi8vd3d3Lndvb3RoZW1lcy5jb208L2xpPjxsaT48c3Ryb25nPndvb19hZF91cmxfMjwvc3Ryb25nPiAtIGh0dHA6Ly93d3cud29vdGhlbWVzLmNvbTwvbGk+PGxpPjxzdHJvbmc+d29vX2FkX3VybF8zPC9zdHJvbmc+IC0gaHR0cDovL3d3dy53b290aGVtZXMuY29tPC9saT48bGk+PHN0cm9uZz53b29fYWRfdXJsXzQ8L3N0cm9uZz4gLSBodHRwOi8vd3d3Lndvb3RoZW1lcy5jb208L2xpPjxsaT48c3Ryb25nPndvb19hbHRfc3R5bGVzaGVldDwvc3Ryb25nPiAtIGRhcmtibHVlLmNzczwvbGk+PGxpPjxzdHJvbmc+d29vX2F1dG9faW1nPC9zdHJvbmc+IC0gZmFsc2U8L2xpPjxsaT48c3Ryb25nPndvb19ibG9nY2F0PC9zdHJvbmc+IC0gL2NhdGVnb3J5L2RldmVsb3BtZW50LWJsb2cvPC9saT48bGk+PHN0cm9uZz53b29fYmxvZ19jYXRfaWQ8L3N0cm9uZz4gLSA8L2xpPjxsaT48c3Ryb25nPndvb19jYXRtZW51PC9zdHJvbmc+IC0gZmFsc2U8L2xpPjxsaT48c3Ryb25nPndvb19jdXN0b21fY3NzPC9zdHJvbmc+IC0gYm9keXsNCgliYWNrZ3JvdW5kOiB1cmwoL3dwLWNvbnRlbnQvd29vX3VwbG9hZHMvYmdyLmpwZykgIzIxMjYyYSByZXBlYXQteCB0b3A7DQoJY29sb3I6ICNiZmM3Y2Q7DQp9PC9saT48bGk+PHN0cm9uZz53b29fY3VzdG9tX2Zhdmljb248L3N0cm9uZz4gLSBodHRwOi8vZmxhc2hjYW1vLmZsYXNoYXJ0b2Z3YXIuY29tL3dwLWNvbnRlbnQvd29vX3VwbG9hZHMvNS1mYXZpY29uLTEuaWNvPC9saT48bGk+PHN0cm9uZz53b29fZXhfZmVhdHBhZ2VzPC9zdHJvbmc+IC0gdHJ1ZTwvbGk+PGxpPjxzdHJvbmc+d29vX2ZlYXRoZWlnaHQ8L3N0cm9uZz4gLSA8L2xpPjxsaT48c3Ryb25nPndvb19mZWF0cGFnZXM8L3N0cm9uZz4gLSAzNiwgNDcsIDg5PC9saT48bGk+PHN0cm9uZz53b29fZmVlZGJ1cm5lcl91cmw8L3N0cm9uZz4gLSA8L2xpPjxsaT48c3Ryb25nPndvb19nb29nbGVfYW5hbHl0aWNzPC9zdHJvbmc+IC0gPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPg0KdmFyIGdhSnNIb3N0ID0gKCgiaHR0cHM6IiA9PSBkb2N1bWVudC5sb2NhdGlvbi5wcm90b2NvbCkgPyAiaHR0cHM6Ly9zc2wuIiA6ICJodHRwOi8vd3d3LiIpOw0KZG9jdW1lbnQud3JpdGUodW5lc2NhcGUoIiUzQ3NjcmlwdCBzcmM9JyIgKyBnYUpzSG9zdCArICJnb29nbGUtYW5hbHl0aWNzLmNvbS9nYS5qcycgdHlwZT0ndGV4dC9qYXZhc2NyaXB0JyUzRSUzQy9zY3JpcHQlM0UiKSk7DQo8L3NjcmlwdD4NCjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij4NCnRyeSB7DQp2YXIgcGFnZVRyYWNrZXIgPSBfZ2F0Ll9nZXRUcmFja2VyKCJVQS0yODY0MDM2LTQiKTsNCnBhZ2VUcmFja2VyLl90cmFja1BhZ2V2aWV3KCk7DQp9IGNhdGNoKGVycikge308L3NjcmlwdD48L2xpPjxsaT48c3Ryb25nPndvb19ncmF2YXRhcjwvc3Ryb25nPiAtIHRydWU8L2xpPjxsaT48c3Ryb25nPndvb19pbWFnZV9oZWlnaHQ8L3N0cm9uZz4gLSAyNTA8L2xpPjxsaT48c3Ryb25nPndvb19pbWFnZV93aWR0aDwvc3Ryb25nPiAtIDM5MDwvbGk+PGxpPjxzdHJvbmc+d29vX2ludHJvPC9zdHJvbmc+IC0gPHAgYWxpZ249ImNlbnRlciI+Rmxhc2ggQ2Ftb3VmbGFnZSBpcyBhbiBvcGVuIHNvdXJjZSBmcmFtZXdvcmsgZm9yIHNraW5uaW5nIEFTIDMgQXBwbGljYXRpb25zLiBUaGlzIHNpdGUgaXMgeW91ciBiZXN0IHJlc291cmNlIGZvciBnZXR0aW5nIHVwIGFuZCBydW5uaW5nIGFzIHF1aWNrbHkgYXMgcG9zc2libGUhPC9wPjwvbGk+PGxpPjxzdHJvbmc+d29vX2xvZ288L3N0cm9uZz4gLSBodHRwOi8vZmxhc2hjYW1vLmZsYXNoYXJ0b2Z3YXIuY29tL3dwLWNvbnRlbnQvd29vX3VwbG9hZHMvNi1sb2dvLmpwZzwvbGk+PGxpPjxzdHJvbmc+d29vX21hbnVhbDwvc3Ryb25nPiAtIGh0dHA6Ly93d3cud29vdGhlbWVzLmNvbS90aGVtZS1kb2N1bWVudGF0aW9uL292ZXItZWFzeS88L2xpPjxsaT48c3Ryb25nPndvb19tZW51cGFnZXM8L3N0cm9uZz4gLSA8L2xpPjxsaT48c3Ryb25nPndvb19yZXNpemU8L3N0cm9uZz4gLSB0cnVlPC9saT48bGk+PHN0cm9uZz53b29fc2hvcnRuYW1lPC9zdHJvbmc+IC0gd29vPC9saT48bGk+PHN0cm9uZz53b29fdGhlbWVuYW1lPC9zdHJvbmc+IC0gT3ZlciBFYXN5PC9saT48bGk+PHN0cm9uZz53b29fdGhlX2NvbnRlbnQ8L3N0cm9uZz4gLSBmYWxzZTwvbGk+PGxpPjxzdHJvbmc+d29vX3VwbG9hZHM8L3N0cm9uZz4gLSBhOjM6e2k6MDtzOjY4OiJodHRwOi8vZmxhc2hjYW1vLmZsYXNoYXJ0b2Z3YXIuY29tL3dwLWNvbnRlbnQvd29vX3VwbG9hZHMvNi1sb2dvLmpwZyI7aToxO3M6NzM6Imh0dHA6Ly9mbGFzaGNhbW8uZmxhc2hhcnRvZndhci5jb20vd3AtY29udGVudC93b29fdXBsb2Fkcy81LWZhdmljb24tMS5pY28iO2k6MjtzOjY4OiJodHRwOi8vZmxhc2hjYW1vLmZsYXNoYXJ0b2Z3YXIuY29tL3dwLWNvbnRlbnQvd29vX3VwbG9hZHMvMy1sb2dvLmpwZyI7fTwvbGk+PC91bD4=