Using Flash to Skin Flex Components

I’ll add more later… busy…

package
{
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BlendMode;
	import flash.display.DisplayObject;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	
	import mx.core.UIComponent;
	
	[DefaultProperty("children")]
	public class FlashSymbolContainer extends UIComponent
	{
		
		private var _children:Array;
		private var childrenDirty:Boolean = false;
		
		public function get children():Array { return _children; }
		public function set children(value:Array):void
		{
			if(value != null)
			{
				_children = value;
				childrenDirty = true;
				invalidateProperties();
			}
		}
		public function FlashSymbolContainer()
		{
			super();
			
			width 	= 300;
			height 	= 200;
		}
		
		protected override function commitProperties():void
		{
			super.commitProperties();
			
			if(childrenDirty)
			{
				childrenDirty = false;
				redraw();
			}
		}
		
		private function redraw():void
		{
			if(_children == null)
				return;
			
			var len:int = _children.length;
			if(len == 0)
				return;
			
			for(var index:int = 0; index < len; index++)
			{
				var obj:DisplayObject = _children[index] as DisplayObject;
				if(obj == null)
				{
					throw new Error("Children must be of type DisplayObject.");
					return;
				}
				
				if(obj.parent)
					obj.parent.removeChild(obj);
				
				addChild(obj);
			}
		}
	}
}

22 Replies to “Using Flash to Skin Flex Components”

  1. This seems like an improved workflow over constantly having to update PNG assets and migrating them over. I’d be curious about two things a) maintainability from the designer’s standpoint and b) benefits in compiled app’s SWF size

  2. Awesome. That is incredibly handy, thank you for sharing. Why didn’t you narrate though? Add some music or something ;)

    1. lol, oh yeah. I remember the one Grant Skinner did awhile ago where he measured enterFrame. Made a lot of sense at the time, but nowadays, I and others are just using Flash for the artwork in Flex, so this assumes absolute position. Definitely don’t want to go that route.

  3. Thanks for the post mate! However, what’s the difference between using FlashSymbolContainer with MovieClips and a typical Flex container and UIMovieClips (created using the Flex Integration Kit)? Cheers

  4. @Guillaume UIMovieClip does a lot more. The whole purpose of the enter frame is to measure the component as it animates so that it’ll work in Containers (VBox/VGroup, etc). If you’re not creating animations, there is zero point to run an enter frame event every frame. Worse, it creates a brand new event listener for every graphic. For larger Flex applications, this doesn’t scale at all. Third, and also important for continuous integration purposes, it actually requires you to compile inside of the Flash IDE. 11 years later and we still can’t really integration the Flash IDE into an automated build process without insanity. Thus, the only solution is to remove all code from the FLA. Most source control systems expect ASCII code, and this solutions no code goes into the resulting SWC, just graphics.

    1. In most of the case where I used UIMovieClip I always avoided the measurement feature by extending the class and removing it (removing the enterFrame if not in transition) since it cost too much in computation, and I get all the state + state transition sugar (and it does work in large project). I understand the need to remove the code from the fla but since your still bound with the class linkage system I think you remain coupled to the Flash IDE and in the insanity circle =).

  5. Is there any reason why someone shouldn’t use the SpriteVisualElement class to wrap the flash symbol instead of the FlashSymbolContainer? It is supposed to be a very light-weight class that exists for reasons like these and some FXG use cases.

    1. SpriteVisualElement is a heavy weight class for handling all Flex container measurement, layout, and invalidation. This includes all the basic DisplayObject features as well as some enhanced shader abilities. It cannot, however, be used via MXML to layout children that I’ve found. It has no [DefaultProperty] annotation to automatically assign children, thus, you need to use ActionScript which isn’t very designer friendly. If I wanted to use ActionScript to lay things out, I’d go back to pure ActionScript 3 and MinimalComps, not Flex.

      I just want to show a vector graphic on the screen, strongly typed, with the ability to have a quick and easy workflow. Most all of the graphics are skins, and thus are not animating MovieClips, and therefore don’t need to be measured. While you can use constraints or percentage based layouts internally in a skin, the graphics themselves can be hardcoded to the size they are for absolute positioning within the skin parts.

      If that’s all you need, to show a graphic on the screen using MXML, my class is the way to go.

      1. I have to admit I haven’t noticed that you’re adding it through mxml. Somehow I missed a pretty big detail :D. I get what you mean and I think I’m gonna try the class as well. Thanks and keep them coming.

  6. Hi Jesse!

    Great tutorial – followed it to the letter, but i get a [Slider-client (Flex)] Could not resolve to a component implementation – error.

    Any ideas, what might be wrong?

  7. Turns out the compiler did not include the swc, as no components were on stage.

    Got it to display a button skin – although the skin does not scale to fit the button text?

    1. Heh, that’s a rabbit hole topic. Bottom line, what you design in Flash is what you see in Flex. Scaling graphics is a large topic. Do you want it to scale? What about maintaining aspect ratio? Is it vector? Do the strokes scale correctly? Is this for mobile? Blah blah blah.

      Suffice to say, the quick solution is something like:

      http://pastebin.com/C7K2Mqrv

    1. The Flash IDE cannot do scale9 for bitmaps, only for vector. If you do it for vector, it should work. If you need it for bitmaps, you’ll have to use the [Embed] tag so mxmlc can do his magic.

Comments are closed.