Core philosophy: Build a component set targeted at rich experience creators.
Main objectives
- Size and performance: Reduce file size for downloads and minimuze CPU/memory impact
- Easy skinning & stlying: Simplify the workflow for customizing the appearance of components
- Extensibility: Make the architecture more approachable to encourage customization
- Knowledge portability: Ensure user knowledge can be transferred from the Version 2 components and Flex.
Size and performance
Size:
- Reduced size vs. v2 by 25-40% (depending on components used)
- Base size: ~10kb smaller than v2 (27KB vs. 17KB). ~110kb smaller than Flex 2.
Performance
- Lower CPU, higher capacity.
- Inherent AS3 performance gains.
- Also took advantage of new features: event model, strong typing, Dictionary.
- No more recursive lookups.
He's showing a demo of a List component with 1,000,000 items in the list and it's scrolling smoothly. He selects 100,000 items and it's almost instantaneous.
Skinning and styling: simplicity and power
Visual skinning
Process:
- Drop component on stage.
- Double-click component.
- Edit assets.
- Rinse, repeat.
Tip: You can use graphic symbols with Scale-9 for sharing component assets.
Limitation: No author-time preview
Everything is visually editable.
You can also use programmatic skinning if you want to.
Process:
- Option 1: Bind a class to the skin clip
- Option 2: Write timeline code on the skin clip
You just need to expose the width and height setters.
Stlying:
Styling lets you apply skins, text formats, and other style settings to instances, all components, or all components of a certain type.
Usage:
import fl.managers.StyleManager; // Change a style on a single instance myInstance.setStyle("styleName", styleValue); // Change a style for all components StyleManager.setStyle("styleName", styleValue); // Change a style for instances of a specific component StyleManager.setComponentStyle(component, "styleName", styleValue);
Styling no longer causes an inefficient recursive look-up system. So you can style at runtime without a performance hit.
Instances as skins:
Advanced feature. You can now use an instance as a component's skin.
Demo: Using a dynamically loaded asset as an icon skin. Grant loads a semi-transparent PNG using a Loader and sets it as the icon for a button.
Demo: Using instance skins to programmatically skin a slide. This rocks: Grant passes a Sprite instance as the track skin for a slider and updates the gradient fill in it at runtime.
Note: Only a single component instance can use an instance as a skin.
Lists: TileList, DataProvider and CellRenderer
TileList: New list type.
DataProviders
No longer obscured as an Array mix-in. Mandatory for use with lists. Sync multiple lists using the same DP.
// data can be an Array, XML, etc. myList.dataProvider = new DataProvider(data);
Methods: addItem, removeItem, replaceItem, merge, invalidate, sort, toArray, etc.
Events: DataChange and PreDataChange events show the type (add, remove, replace, sort) and the indexes/items affected.
CellRenderer
Extend the CellRenderer class to create your own custom cell renderer.
import fl.controls.listClasses.CellRenderer; public class MyRenderer extends CellRenderer { // ... }
Or implement ICellRenderer: x, y, data, listData, selected, setSize, setMouseState.
Architecture: behind the scenes
Shallow, linear class hierarchy without mixins and a clear inheritance structure (limited use of composition). Makes use of protected members with few private or namespace-protected members. In short, you can extend pretty much anything. Uses consistent coding standards.
To create your own components, you extend UIComponent and can, if you want to, make use of the InvalidationType, ComponentEvent, StyleManager and FocusManager classes.
To create a custom list called MyList, for example, you would extend the SelectableList class, which extends BaseScrollPane, which extends UIComponent. Although the list classes are probably among the most complicated, the inheritance hierarchy is relatively shallow.
The framework allows for the granular invalidation of specific aspects of a component. e.g., foo.invalidate(InvalidationType.SIZE); All invalidated aspects of a component get redrawn at the next RenderEvent.
There is a registration-based style model where components register for specific styles. Supports style inheritance and pass-through styles.
The components support smooth scrolling (pixel level scrolling on all List-based components, as opposed to cell-level scrolling).
The framework has smart renderer reuse. Renderers are reused intelligently, leading to less flicker than in the Version 2 components.
The Bad
Although the components are a huge step forward when compared to the Version 2 components, Grant wants to point out some of their limitations. These include:
- No databinding or data components. These features are apparently not commonly used in the the experience market.
- No CSS (uses a simplified style model instead).
- No tree or accordion components.
- API variances (some component interfaces differ from those in Flex 2).
This was a hugely informative session and was very well presented.
The Flash CS3 Components article by Aral Balkan, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-Noncommercial 2.0 UK: England License.
I was actually very disappointed with the limited number of AS3 components.
No data components (their excuse is lame),. no datagrid, no window, no tree or menu? What they are actually are saying is ‘if you need this functionality, get Flex’, which is not quite fair.
Thanks again dude. EP.
Extending CellRenderer was a nice choice..
Well thought out in terms of avoiding mixins and limiting private and namespace variables.
A true test for me will be when i incorporate a full flash codebase into a flex project and see how many hurdles i run into.
Well I really don´t miss this datacomponents and the according GUI stuff
Nothing much out there for component developers. Reading the supplied docs leaves more questions than answers.
Where and how is the live preview created? Why no sourcecode for ComponentShim (fl.core.ComponentShim)? 2 hits on Google! What is this black magic anyway?
What’s the workflow for new component development? Why no documentation on this subject? I want to know how it works, not how to use it…
Did Grant give any information as to when he/Adobe might be releasing more info on this front?
I don’t miss the data components, but I do miss their classes, especcially the RDBMSResolver class….sigh.
I think this is a great step forward - I might actually use the components now!
However, I still think it would be better for Adobe to actually embed some basic components into the flash player so that they don’t have to be added to every single SWF that needs to use them.
What does this even mean, “No databinding or data components. These features are apparently not commonly used in the the experience market.”
Did you mean, ‘experienced market’? As in pro users don’t bother to use the available classes? Or in their experience they are infrequently used?
Hell I use the databinding classes, the dataset class, the RDBMSResolver class, all day long. I’ve even setup my own template Directions, Vehicle, and Model classes based on the said classes….I’m so sad about that. I don’t have the time to rebuild the classes myself…
I’m looking for sample code to build my own components. I loved the person13.com text on creating custom components in AS2, and actually ended up building well over 60 of them…
If anyone has a lead on that : mlegris _ à _ newcommere _ point _ ca
thanks!
There still isn’t a component that allows text to be vertically aligned, kinda’ like tables have been able to do since HTML … I don’t even know which version.
While we’re at it, assuming anybody from Macromedia even reads these things, what’s up w/ the number of packages? I can’t think of another programming language where I have to import so much stuff just to do simple things.
I’ve written an article about building non FLA-based components. Of course it’s not new for those who know how to build AS2 components but there are people out there who think that the new architecture is the only one.
The article can be found here: http://flexion.wordpress.com/2007/06/27/building-flash-cs3-components/
Regards!
spender wrote:
“Nothing much out there for component developers. Reading the supplied docs leaves more questions than answers.
Where and how is the live preview created? Why no sourcecode for ComponentShim (fl.core.ComponentShim)? 2 hits on Google! What is this black magic anyway?
What’s the workflow for new component development? Why no documentation on this subject? I want to know how it works, not how to use it…
Did Grant give any information as to when he/Adobe might be releasing more info on this front?”
———————\
Yes, the lack of documentation is very weird, and frustrating … I did copy this from a blog I read (sorry, neglected to copy the authors name - forgive me for not giving credit) hopefully it’s helpful
A work-flow for component creation
Introduction
The new component architecture in Flash CS3 is a vast improvement on the V2 component architecture used in Flash MX2004 and Flash 8. Fundamentally, the problem with the V2 architecture was that skinning a component was unintuitive at best and painful the rest of the time. This meant that they were unsuited to the people who would benefit from them the most, namely the large Flash designer community who gain from the functionality of components but don’t have the skills or patience to go through some monster skinning process. This walkthrough is intended to describe the work-flow of component creation. It does not cover any of the details of actually coding components or any of the architectural details of the new fl.core.UIComponent class.
With the arrival of Flash CS3, Adobe has introduced a new component architecture that no longer uses the .SWC file as a container for ActionScript3 components. Components are now delivered to the end user in the form of a .FLA file. A correctly formed .FLA file placed in the correct folder [ $(AppConfig)/ Components ] will present the components that it contains in the components panel of the Flash IDE.
When the end user drags a FLA based component out of the components panel into their Flash document, a number of things happen:
An instance of the component is created in the document. At author-time, a live preview is displayed, which generally uses the default skin of the component.
A number of additional items are also imported in to the library. Mainly these are the skins of the component, and also a mysterious compiled clip called ComponentShim (more about this later…)
The very thought of handing a V2 component to a designer for them to reuse, was in my opinion, quite a laughable concept. This is where the new .FLA based components really shine.
The real advantage of FLA-based components is that the user is now able to double click the component, and edit the library resources that it uses. This means that components no longer feel locked-down, and the look of the component can be easily customized without a degree from the Macromedia V2 School of Rocket Science™. This paves the way for components to start being really useful in situations where there are clear divisions between programming and design. With the advent of ActionScript 3, it’s possible that the gap between development-oriented and design-oriented Flash users will widen. The new component architecture offers a bridge over the chasm.
I’m not going to spend too long describing how to use the new components. This is well covered in the CS3 documentation, and there is more info over at Aral’s blog and more recently on Grant Skinner’s blog.
My interest in components is from the perspective of a programmer lacking in design skills. Components will allow me to deliver easily re-usable functionality without tying the users of the component to my (rather poor) concept of a look and feel. So I need to know how to make component .FLA files that work in the same way as the ones delivered with CS3. Let’s start setting up a simple component…
Setting up our first component
1. Create an empty Flash ActionScript 3 document. Save it in an empty folder as CustomComponents.fla
2. Add the following class path to the document’s settings:$(AppConfig)/Component Source/ActionScript 3.0/User InterfaceThis is where the core component code resides (in particular fl.core.UIComponent)
3. Create an ActionScript class for your component. Save it as MyComponent.as in the same folder as the CustomComponents.fla file.The class should extend fl.core.UIComponent, so the opening lines of your component class should look something like this:
package
{
import fl.core.UIComponent;
import flash.display.*;
public class MyComponent extends UIComponent
{
var mc:MovieClip;
public function MyComponent()
{
super();
}
protected override function draw():void
{
if (mc == null)
{
var classDef;
try
{
classDef=this.loaderInfo.applicationDomain.getDefinition(getSkinName());
}
catch (e:ReferenceError)
{
//there’s no guarantee the try block will work
//as the skin may be missing
//in which case, abort!!!
return;
}
mc=new classDef as MovieClip;
addChild(mc);
}
mc.width=width;
mc.height=height;
}
protected function getSkinName():String
{
return “MyComponentSkin1″;
}
}
}
4. Create a MovieClip symbol in the library, and change its name to “Avatar” (users of the V2 architecture are more likely to remember this as the asset formerly know as BoundingBox, and functionally, the Avatar fulfills a similar role). Enter edit mode on that symbol, and on frame 1 (the only frame) draw a rectangle with x and y coordinates of 0 and no fill. It’s probably best to use a hairline stroke, as when this symbol is used later, it is likely to be scaled, which will do odd things to non-hairline strokes.
5. Create a MovieClip symbol in the library, and give it the same name as the class you defined above (e.g. MyComponent)
6. Edit this symbol, and rename layer 1 to Avatar, and drag in the Avatar symbol from the library to x and y coordinates of 0. Ensure that this is the only symbol instance on frame 1 of your component MovieClip. UIComponent will use this instance to set its default width and height, and then remove it from the display list immediately. It only does this for the DisplayObject at index 0, so we don’t want any other display objects on this frame.
7. Create a new layer called “skins”, and create an empty key-frame on frame 2. This is where we will be placing subsequent symbols from the library that represent the various skins for our component.
8. Create a new MovieClip symbol in the library and call it MyComponentSkin1 (this time, in the linkage properties, check “export for AS” and “export in 1st frame”, and enable 9-slicing). Draw something pretty on frame 1.
9. Edit frame 2 layer “skins” of MyComponent, and drag MyComponentSkin1 from the library into this frame. Don’t worry about positioning it… it’s never used at runtime; this is the view that will open when the user double clicks the component. When the component gets more complicated, it might be worth adding a guide layer to this frame with some labels for the various skin assets.
10. Right click MyComponent in the library and choose Linkage… In the following dialog box, provide the following details:Class: MyComponentBase class: flash.display.MovieClipCheck “Export for ActionScript”Check “Export in first frame”
11. Right click MyComponent in the library and choose Component Definition… In the following dialog box, provide the following details:Class: MyComponentThere are several other options on this panel that can be configured, but leave them (for now…)
What is a ComponentShim, and why do I need one?
Tracking down the ComponentShim
One of the more confusing aspects of the new FLA-based architecture is a compiled clip called ComponentShim. The documentation refers to it only once with the following rather cryptic line:
“The ComponentShim SWC is placed on Stage on Frame 2 in every User Interface component to make available the precompiled definitions.”
That’s all you get. A web search turns up even less. A quick search of the CS3 file system finds no .SWC file called ComponentShim. The only clue is a file called ComponentShim.fla, which has provided some insight into the purpose and creation of the ComponentShim.
If you pull any of the components supplied with CS3 out of the components panel into a new document, along with the component skins, one of the additional symbols that is imported into your library is a Compiled Clip called ComponentShim It is placed in a library folder called “_private”. An instance of ComponentShim can be found on frame 2 of all of the components supplied with CS3 (in User Interface.fla). A few questions immediately spring to mind… Why is it there? How is it made?
V2 architecture developers are probably familiar with compiled clips. These are non-editable MovieClips in the library that contain their own assets and code in a ready-compiled format. Indeed, in the not-so-distant past, when you dragged a V2 component from the components panel onto the stage, its symbol instance in the library was of type “compiled clip”. When they are used in a project, the contents of the compiled clip are built in to the resultant SWF, without any need to recompile the code that they contain. If classes in the precompiled code of a compiled clip are not used in a client project, then the byte code for those classes is not copied into the resulting SWF. It turns out that this behaviour is a great benefit to the FLA-based component architecture, and gets us out of some tricky issues.
Looking at component usage
When the end user drags a component (without a ComponentShim) into their project, a number of items are added to the library. These are the component item itself, and all the associated assets of the component. When the time comes for the user to publish their project, a problem arises… the component is derived from (in our case) the MyComponent.as code, which is in turn derived from UIComponent. However, in the end-user’s project, neither of these files is in the document’s class path (if you remember when setting up the component FLA, additional class paths needed to be added). When document is exported, Flash sees that MyComponent uses class MyComponent, but cannot find a definition for MyComponent. So, by default, it auto-generates its own version of the MyComponent class, a very simple subclass of MovieClip, with no other code and no reference to UIComponent. MyComponent doesn’t work, because it has no code, and ends up with the behavior of a basic MovieClip.
ComponentShim to the rescue
As a component developer, sometimes we don’t want to supply our component code to the end user. Even if we do, we don’t want them to jump through the additional hoop of setting up their class path to include the MyComponent code and the UIComponent code. This is where the ComponentShim comes to the rescue. If all the required code is included in a precompiled format in the component’s assets, it means that we don’t have to supply the component code, nor is there a requirement for the end-user to set-up their class path to include the necessary code. The ComponentShim is a precompiled clip containing all the classes that are used by components in the component .FLA, but with none of the assets. With the ComponentShim included as an asset, this code is already available and no further action is required by the end user to get this code working with the component they are trying to use. An added benefit is that when the end-user compiles their project, they don’t need to recompile the component code every time they export.
How to make a ComponentShim
1. Create a new ActionScript3 Flash document.
2. Set up the class paths for the document with exactly the same paths as in the component .FLA we created above
3. For each component in the original component .FLA, create a MovieClip symbol in the library. In the linkage settings set its class to the class used by the component and ensure that “Export for ActionScript” and “Export in first frame” are checked.
4. Add one more symbol to the library, called “ComponentShim source”. (I have found that it is useful to put some sort of graphic/text on frame 1 of this symbol, something Adobe does not do. With no graphical presence, when we use it later it is easy to lose the instance on the stage, as it completely disappears. Once again make sure that “Export for ActionScript” and “Export in first frame” are checked in the linkage properties of the symbol. Associate it with some non-existent class, so that Flash auto generates a class for it. I’d suggest then class name “ComponentShim”, but technically the choice of name is completely irrelevant, as long as there is no collision with other class names.
5. Right click the ComponentShim symbol in the library, and choose “Convert to Compiled Clip”.
6. If all the classes compile correctly, then a new compiled-clip symbol will be created called “ComponentShim source SWF”. Select the symbol in the library and rename it to “ComponentShim”. This is now in essence a compiled repository of all the component code, with none of the associated assets.
7. Drag the “ComponentShim” symbol from its library into your component .FLA library.
8. For each component in your FLA-based component library, drag an instance of ComponentShim from the library on to frame 2 of the component. If you are working through this walkthrough, then currently the only component in the library is “MyComponent”, so you will need to do this only once.
A working component. Kind of…
By this point, we should now have a working component. If we copy the component .FLA into the correct folder [ $(AppConfig)/ Components ] and restart Flash, then we will see a new branch in the Components Panel tree view labeled with the name of the .FLA, and with MyComponent as a sub-item. However, when this is dragged onto the stage, we do not see a rendition of our beautifully designed component. All we see is its bounding box (the Avatar instance we dropped on frame 1 of our component). It behaves in every way like a normal MovieClip that has been associated with a class. It has no live preview. Nowhere in the process above did we precompile a working version of our component for use as a live preview. This is one area where V2 SWC based components were better, because the generation of a live preview was done automatically. For FLA based components, it is necessary to create a live preview by hand.
Finishing the job
Creating a live preview SWF for the component
Hidden in the documentation is a new class called fl.livepreview.LivePreviewParent. In the linked document, two different methods are outlined for creating a live preview SWF. One of them is a hack and involves creating a SWC file from your component, renaming the SWC file so it has a ZIP extension, and extracting the SWF file that it contains.
Unless I have missed something, I think CS3 is a let down on this front. How easy would it have been to add new option somewhere near “Export SWC file…” that exported only the live preview SWF automatically? It could even automatically take care of hooking it up to the component.
In order to gain an understanding of what a live preview SWF is, I worked through the second (9 step) method for creating a live preview SWF. The steps for doing this are copied verbatim from the fl.livepreview.LivePreviewParent documentation:
1. Create a new Flash document.
2. Set its document class to fl.livepreview.LivePreviewParent.
3. Drag your component to the Stage and position it to x and y coordinates of 0.
4. Check to ensure that the component parameters remain at their default settings. This should be the case if you drag the component from the Library panel or from the Components panel.
5. Select Modify > Document from the main menu and, for the Match option, click Contents.
6. Click OK.
7. Publish the file to see the resulting SWF file as a custom live preview SWF file.
8. Right-click the asset in the Library panel and select Component Definition from the context menu.
9. The Component Definition dialog box allows you to specify a custom live preview SWF file for a component.
Steps 8 and 9 here are slightly misleading here, as it is not made clear that you should be operating back in your original document’s (CustomComponents.fla) library, not the library of the newly created document.
A fully working FLA-based component
At this point, you can save CustomComponents.fla and close Flash. Copy CustomComponents.fla to $(AppConfig)/Components and reopen Flash. Create a new ActionScript3 Flash file and open the components panel. You will see the CustomComponents entry, and within it, the new MyComponent. When this is dragged to the stage, it works just as a component should. Job done.
oops, that was you. You answered your own question!!
Well, thanks for the info, it helped me out (some - I’ve still got plenty of questions on this topic)
The Flash CS3 components poses a serious nightmare for developers.
When nested within other classes, the components do not work properly at all.
The ramifications of encapsulating the components classes poses more serious issues.
E.g. Try including components in nested swfs. They simply stop working.
Biniging was always poinless I freelanced for a number of London companies and not one has the Creative Supervisor ever asked me to use them. An Array had always been a data provider so its easier to create a class to PARSE incoming XML into components, instead of messing about with Component Inspector.
The tree component is quite simple to make as long as you addChild(tree_mc) to every xmlNode that hasChilds. So a tree component isnt impossible to make.
An accorian if you are a serious developer can also be created from scratch. It just movieclips on different depth levels.
But I wont front, they did make things a bit easier when they were there.
I like CS3 and I like AIR they’re untouchable.
OMIT *** I meant Binding is POINTLESS!
Every thing is ok
To Some Extent I managed to develop it
but Not able to insert Metadata to component
How to create it
Not sure i understand what Adobe are trying to achieve with the latest version of flash in particular the component selection and the lack of data components.
Web sites are constantly evolving and adding extra functionality, integration to other systems which is clearly the way forward, so the lack of data components, web services does seem strange and i agree the rationel behind their decision to omit these from this release simply doesn’t make sense.
I think what they did is a shame. There is simply no excuse for omitting data components and data binding, saying they were not used anyway is just lame. Becouse of this decision Flash ceased to exist as a RIA tool, it remains only a toy for designers, unable to carry out serious tasks. I think it’s an agressive marketing strategy to force people to purchase flex, which is much more expensive. It’s sad that Adobe has to “kill off” a well working product line just to attract customers to a more expensive one. Anyway, while this could work on the short term, it will definitly betray itself on the long term, exspecially when competitors like silverlight 2.0 are knockng on the door.
Are the demos referred to in the “Instances as skins” sections posted anywhere? I’ve been trying to find the best way to programmatically skin components in Flash, but haven’t really found a good tutorial. Its easy to do in Flex by extending ProgrammaticSkin (mx.skins.ProgrammaticSkin) but this class isn’t available in Flash. Any help greatly appreciated!!
Roland wrote:
>It’s sad that Adobe has to “kill off” a well working product
>line just to attract customers to a more expensive one.
This is false; Flex is actually the cheaper product-it’s free(!) and can be downloaded from Adobe’s website. One way in which the Flash CS3 components seem interesting: trying to use Flex components in a pure AS3 project is a pain in the neck.