MXML without Flex Framework/Components - apache-flex

The Flex compiler can compile "pure AS3" SWF files that don't contain any Flex Component bytecode. So,
Would it be possible to create a custom component framework (used in place of the Flex Framework), that can still be visually laid out using MXML (read: markup), and compiled down to a SWF without any dependencies on the Flex Framework itself?

Yes, it's possible. Your MXML files are essentially just a different way to specify classes. You can see what mxml files boil down to by compiling your project and providing -compiler.keep-generated-actionscript=true to mxmlc.
bar.mxml:
<?xml version="1.0" encoding="utf-8"?>
<flash:Sprite xmlns:flash="flash.display.*">
</flash:Sprite>
After compiling with mxmlc -compiler.keep-generated-actionscript=true bar.mxml, it turns into the following.
generated/bar-generated.as:
package {
import flash.display.Sprite;
// bunch of imports
public class bar extends Sprite {
public function bar() { super(); }
}
}

There are two different compilers: one that is used for compiling ActionScript code to AVM bytecode and another (mxmlc) that compiles MXML files into ActionScript code which is then in turn compiled by the first compiler. If you want to see what AS3 code is generated, pass the "-keep" parameter to the MXML compiler.
In theory it's possible to do what you suggest. My guess is that mxmlc keys heavily into features from the UIComponent class, so you'd probably have to hack on mxmlc a bit so that it didn't puke on non-UIComponent classes. Even still, since things like [Bindable] / data binding make use of Flex framework features (not plain Flash Player / AVM features) you would be rewriting an awful lot of code.

Related

How to use FXG as mx:Button icon

I'm trying to use a FXG image as the icon for a button that also contains a caption. My FXG file is located at resources/SpeakerIcon.fxg and my attempted usage looks like this in my mxml file:
<mx:Button id="audioButton" label="Audio"
....
icon="{resources.SpeakerIcon}"/>
When I try to use this I get "TypeError: Error #1034: Type Coercion failed: cannot convert resources::SpeakerIcon#41fa0e1 to mx.core.IFlexDisplayObject." My research indicates that FXG files should be s:Graphics which do implement IFlexDisplayObject http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/spark/primitives/Graphic.html.
What simple thing am I missing?
The <s:Graphics/> object is different than the <Graphics/> tag in an FXG document.
<s:Graphics/> is the base class for Spark primitive shape components (like <s:Rect/>). These are not as lightweight as their FXG counterparts. As such they do not implement the IFlexDisplayObject interface (as #Flextras has just posted :)
FXG assets can be treated as SpriteVisualElement in your Flex code, which technically means FXG assets implement the IVisualElement interface.
If you can, use the Spark <s:Button/> class instead of mx. I don't think <mx:Button/> works with FXG.
For an FXG you should use a Sprite or [in your case] a SpriteVisualElement. I don't believe either of those classes implement IFlexDisplayObject.
You may consider wrapping your FXG element up in this FXGImage class from my Apache Flex whiteboard. FXGImage extends UIcomponent which is an IFlexDisplayObject.
Here is a direct link to the source code for the class.

What is the purpose of 'fb:purpose' in a Flex <fx:Script>?

I've now seen it a few times here and there and it's got me curious.
<fx:Script fb:purpose="styling">
//script stuff
</fx:Script>
So far, I have seen no difference with it there and without it. Nor do I get any compiler erros. How does a script with fb:purpse differ from a script without? What are the consequences for not including a fb:purpose and what are the benefits for including a fb:purpose?
From the Flex 4 documentation:
Most Spark skins have a special block at the top of the skin class. This block typically defines style properties that the skin class respects, including the exclusions that the skin uses. The tag includes a special attribute, fb:purpose="styling":
<fx:Script fb:purpose="styling">
This attribute is used by Flash Builder. When you create a copy of a skin class in Flash Builder, you can opt to make the skin styleable. If you choose to make it styleable, Flash Builder includes this section of the skin class. If you choose not to make the skin styleable, Flash Builder excludes this section.
It's part of the flashbuilder namespace, and won't have any effect on compilation.
There's no documentation for it that's publicly available at the moment, but it's usually generated by FlashBuilder itself, or is included in the Flex framework code from Adobe.
It's used to show the purpose (in a tool readable manner) of a script block, in this case, styling.
If you create a new MXML Skin using Flash Builder (File > New > MXML Skin) you can deselect the "Remove ActionScript styling code" checkbox which signifies that Flash Builder should remove the script block that defines fb:purpose="styling".
As Yaba said, it allows you to check or uncheck "Remove ActionScript Styling" when building a new MXML skin by copying another Skin class.

How to make bindable property in Actionscript Project

I have seen a lot of codes regarding how to bind property in Flex project. Such as this code in Flex Help:
var watcherSetter:ChangeWatcher =
BindingUtils.bindSetter(updateMyString, myTI, "text");
However, I am creating Actionscript class within Actionscript Project, and I cannot import mx.binding.utils.* into my project. How could I make this works when Actionscript project cannot see this package? Is there any other way to makes property of different object bind together in Actionscript project?
which IDE are you using?
please note, you can always manually import the classes by simply adding a classpath pointing to the flex framework sources with the SDK.
also, do not forget to declare the properties as bindable using the according metatag.

What is the best way to share assets - icons/images - across multiple Flex applications?

I am in the process of creating a new - "lite" - version of a Flex application I created a while ago. I have been porting over many of the Classes and Components to a Flex Library Project that compiles an SWC file. Because both are Cairngorm applications, I'm not able to completely eradicate duplicate code, but it seems logical that I should be able to share assets - such as icons (PNG files). What is the best way to do this? I have tried including them in the SWC, but I can't figure out how to access them in the application. If you can help me figure that out, then my question will be answered. Any thoughts?
Here is and example of how I currently embed icons/images in my Flex application:
<mx:Script>
<![CDATA[
[Bindable]
[Embed(source="assets/icons/cancelIcon.png")]
private var cancelIcon:Class;
[Bindable]
[Embed(source="assets/icons/saveIcon.png")]
private var saveIcon:Class;
]]>
</mx:Script>
Thanks.
0) First, looking at the code above - I recommend some minor changes:
// Actionscript instead of MXML:
public class ResourceClasses
{
Bindable]
[Embed(source="assets/icons/cancelIcon.png")]
public static var CancelIconClass:Class;
// make your variable public and static without public no one
// outside the class can access AND bindable won't matter
}
---- Now, compile your library.
---- If the assets aren't in the right place the compiler will complain
1) In your application, you need to reference the library project / swc
---- You should be able to get code hints / intellisense in Flex Builder / eclipse from classes in your Application to classes in the library project
2) In your Application - Do some code like this:
var image:Image = new Image();
image.source = ResourceClasses.CancelIconClass;
// more image property setting...
someCanvas.addChild(image);
3) This will get you going - using a Library project to hold images, etc...
*** DO NOTE: If the images need to be loaded multiple times, reused, etc -- There are other steps to take to squeeze out the best performance, etc...
This section of the livedocs would be interesting to you:
http://livedocs.adobe.com/flex/3/html/help.html?content=building_overview_5.html.
Do you have a specific example of how you are embedding the assets and trying to use them in the resulting swc that isn't working? Do you think your problem is in the embedding them into the swc or using them from the swc in the actual application?
Well, using #Gabriel's advice, here's what I ended up with:
package
{
[Bindable]
public class ResourceClasses
{
[Embed(source="assets/icons/cross.png")]
public static var CancelIconClass:Class;
}
}
Referenced in my application like this:
<?xml version="1.0" encoding="utf-8"?>
<mx:Box xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Button label="Cancel Changes" icon="{ResourceClasses.CancelIconClass}" />
</mx:Box>
Thanks!

Adding button in Actionscript code : Using Flex Builder

I created a new actionscript project using Flex Builder 3 and tried
to run the following file. I get this error :
Definitions: fl.controls:Button could not be found.
All I want to do is, to add a button to the application.
How could I do it?
package {
import PaperBase;
import org.papervision3d.objects.primitives.Cone;
import fl.controls.Button;
import fl.controls.Label;
import fl.events.ComponentEvent;
public class cone1 extends PaperBase {
public var cone:Cone = new Cone();
protected var sceneWidth:Number;
protected var sceneHeight:Number;
public function cone1() {
sceneWidth = stage.stageWidth
sceneHeight = stage.stageHeight;
init(sceneWidth*0.5,sceneHeight*0.5);//position of the cone
}
override protected function init3d():void {
cone.scale = 5;
cone.pitch(-40)
default_scene.addChild(cone);
}
override protected function processFrame():void {
cone.yaw(1);//rotation speed
}
}
}
The fl.* package is part of Flash Professional, not Flex. For Flex you should be using the components that are part of the mx.* package.
Now, that being said, I'm fairly sure it is possible to use Flash components in Flex. I'm just not sure how it's done off the top of my head.
Also, you don't need an actual button component to get a "button like" ui element - any class that extends InteractiveObject will do. This incldes Sprite and MovieClip.
Branden is correct the fl package is a part of the Flash IDE..I am not sure either but you may be able to add the package to your class path if you know where the package resides on your file system..i am guessing somewhere in C:/program files/adobe/flash
if you want to use components in flex builder I think you need make a flex project not an actionscript project
and change your imports to:
import mx.controls.Button;
import mx.controls.Label;
import mx.events.FlexEvent;
Also if you do not need to use components either you can use a Sprite for a button like branden said and you could just use a TextField for a label.
another option if you have the flash IDE is to make a SimpleButton, press F8 select button, click enter. then give it a linkage name by right clickin it in the library panel and selecting linkage name. then export the .swf and put the swf in the src folder for your project and embed it like this:
[Embed(source="flashfile.swf")]
public var myButton:Class;
You may even be able to export the Flash IDE components this way but not sure...actually I am not 100% positive if the [Embed] meta data works in an actionscript project or just flex projects so you will have to check and see.
It depends what version of the IDE you have, for CS4 and Mac the location would be /Applications/Adobe Flash CS4/Common/First Run/Classes
Add that folder or the relevant folder for your installation/OS to your classpath in flashbuilder/eclipse and it will interpret the class calls fine.
It makes sense if you're coding pure actionscript and dont want to use flex components, or employing a mixed coding and designing in IDE approach.
#philip the embed tag cannot be used in pure actionscript
Not sure why you would want to, but if you need to import the flash libs into flex,try dragging what you want to the stage in flash and exporting as a .swc file to import into your flex project.

Resources