How to use FXG as mx:Button icon - apache-flex

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.

Related

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.

Export SWC from Flash and Access Child from Flex

I'm creating an actionscript project in Flex Builder. I succeed to export from Flash a SWC file, and to use it succesfully in Flex. I have a good programming background and Flex looks very simple for me, but I have difficult times in flash.
I'm trying to achieve something that might be very simple(not for me of course):
I create a simple shape in Flash, convert it to symbol. Then I create a TextField. The I select both the elements and convert them to another symbol, and Export it as a movieclip in swc.
In flex I want to change the value from the textfield. How should I do? I'm trying to do:
var t:ExportedMC = new ExportedMC();
t....(what should I write here)
As I mentioned when I open flash I feel like an elephant in a porcelain store. I have 2 questions here:
- how to assign a name to the textfield in flash? I'm using CS4.
- how to access it as a child in flex?
When you create the symbol in Flash and export it to actionscript (in symbol properties dialog), you created a class that is accessible in Flex (after including the resultant swc in flex project library path). Any controls/shapes/symbols within that class will be contained within and created along with the containing class.
If you have any objects/smybols in that class that you would like to access/modify/whatever, you need to give them an instance name (you can do it without this step, but it's more complicated). In Flash, you edit (doubleclick) the class object in the library, then select a particular sub-object/symbol/control in the class object and give it a name by entering something under in object properties tab. That name will be included in the exported class as an property that you can access as any other class property (width,height,x,y,...).
For example, if you have a ExportedMC symbol that includes a TextField control which you gave instance name ('txtFieldName', for example), you would access it in Flex like so:
var t:ExportedMC = new ExportedMC();
t.txtFieldName.text="something";
Flex will actually be able to autocomplete the property name on the class, so you'll easily be able to know if things worked out or not.
Hope this helps.

does actionscript addChild require a display object first

Solution:
if you have the same problem, addElement() instead of addChild() is what did it
I'm trying to move away from mxml to actionsctipt. I have a <s:Rect> that I've created and set its properties, but having trouble adding it.
var aRect:Rect = new Rect();
//set properties like aRect.x, aRect.y, aRect.width, aRect.height
//tried adding it various ways
addChild(aRect);
Application.addChild(aRect);
Application.application.addChild(aRect);
stage.addChild(aRect);
But I keep getting the error
1067: Implicit coercion of a value of type spark.primitives:Rect to an unrelated type flash.display:DisplayObject
Originally in the mxml, it was right inside <s:Application> not nested inside anything
<s:Application>
<s:Rect id="aRect" x="10" y="10" width="15%" height="15%">
//then fill code here, removed for readability
</s:Rect>
</s:Application>
What's the deal, I thought actionscript would be nicer than mxml.
tried changing addChild(aRect); to addElement(aRect); and that worked beautifully.
It's because Flex 4 significantly changed the way the display hierarchy works in MXML-based applications. This is a bit confusing since addChild() no longer works as simply as you'd want it to - you have to add elements to a dataprovider, and then the logic of displaying those elements (which ones to add where, how to skin them, etc) is handled elsewhere. It's kind of a useful change, though, because it forces you separate your concerns in a very concrete way. Once you have your elements all added to your dataProvider you can swap out Layout objects at will (even at runtime) to change the way your application looks.
EDIT: Technically it's not the displayList itself that they've changed. It's the fact that the basic unit used by Flex is now the "Group" - even s:Application extends group. You add your content to a a Group (or to the top level Application) and then you assign the group a layout to tell it how to display the items you've added.
Yes, you need a DisplayObject. I'm not familiar with spark.primitives.Rect, but perhaps you could just create a new Sprite and call methods on its Graphics object to draw the rectangle?
According to the live docs, the addChild method of the Application class does require it to be a displayObject.
Annoyingly we will often struggle to add flash assets ( swf swc ) (display objects) using addElement.
I'm working on a way to do this right now :( more hoops and jumping
Also my swc is not viewable in the package explorer (why not ?)

MXML without Flex Framework/Components

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.

Flex XML elements vs. code

It's possible within a Flex application, to declare elements, for example a HTTPService elements, both in XML and also in code.
That is, either:
...
or in code:
var hs : HTTPService = ...
My question is when should I prefer which alternative? What are the advantages of having stuff in XML vs. plain old vars in code?
MXML is great for doing declarative layouts, much easier to follow than doing everything programmatically in ActionScript. If you are using something like a ServiceLocator to define HTTPService, RemoteObject, etc in your app then declaring them via MXML is also quick and easy. Basically if you want to add anything to an object's displayList quickly and easily, MXML is a great way.
Elements are more concise and compact than AS3 code, tho of course ultimately it all becomes the same thing. You can, for example in 'one line' of mxml declare an HTTPService and set several of its properties. In script you'd need to do this in many lines of init code. If you have a lot of global variables this can start to become unruly.

Resources