Flex: changing Flex component styles in AS3 - apache-flex

in MXML, there is a Button class which you can instantiate like so:
<mx:Button id="something />
but what if you wanted to dynamically build this in AS3 and add it to the Flex app dynamically, without the use of components (just AS3) and then modify Flex's styles, for example, here you access the Button's properties and set them:
var btn:Button = new Button();
btn.height = 50;
btn.width = 75;
btn.x = 100;
btn.y = 40;
but how would you go about changing the Style, for example:
btn.downSkin = "something";
btn.color = "0xfffff";
I'm sort of starting to lean towards making a flex component in MXMLand than just making it visible true/false, but i like the fact that i create an object in AS3 and then destroy it when I don't need it anymore, than create it again once needed.

This page has a solution to the problem:
Setting and getting Style attributes in ActionScript:
// setting a components styleName to reference a CSS class
component.styleName = "highlight";
// set a Button's background color and font size
submitButton.setStyle( "backgroundColor", 0x000000 );
submitButton.setStyle( "fontSize", 14 );
// get a TextArea's font family and color
textArea.getStyle( "fontFamily" );
textArea.getStyle( "color" );

You could use CSS, either inline or as an external CSS file. That way you don't have to set the properties manually every time you create a button.
/* CSS file */
Button {
borderColor: red;
}
Check out Styling Button control, by Peter deHaan (also read the comments in that post).

Related

add uicomponent inside a sprite

i want to add UIComponent inside a spite. here is the code:
private function make() : void {
var circle : Sprite = new Sprite();
circle.graphics.beginFill(0xFF0000, 0.2);
circle.graphics.drawCircle(0, 0, 20);
var button : Button = new Button();
button.label = "testing...";
var wrapper : UIComponent = new UIComponent();
circle.addChild( button );
wrapper.addChild( circle );
addChild( wrapper );
}
the problem is that button is added, but is not displayed. if i do reversed - add sprite to uicomponent - everything works fine, but this way it doesn't work. i tried to use invalidate functions for button etc... even tried making "circle" as UIMovieClip, but no luck - button is still invisible. also if i simply do "addChild( button );" - it is shown, what the... please help, what i am doing wrong? how can i add a button inside a sprite?
Short answer, you can't. What you CAN do is instead of using Sprite, you use UIComponent for your circle.
The reason for this is that UIComponent has A LOT of code that changes how it behaves, including how to add and layout children. You could essentially take the same code to a Sprite since UIComponent does extend it, however that would be VERY redundant. This works great for me:
private function make() : void {
var circle : UIComponent= new UIComponent();
circle.graphics.beginFill(0xFF0000, 0.2);
circle.graphics.drawCircle(0, 0, 20);
var button : Button = new Button();
button.label = "testing...";
var wrapper : UIComponent = new UIComponent();
circle.addChild( button );
wrapper.addChild( circle );
addChild( wrapper );
}
Unfortunately, in order to use Sprite the way you are trying to do it, you would have to extend Sprite and implement IUIComponent.
Taken from the Flex 3 Language Reference:
Note: While the child argument to the
method is specified as of type
DisplayObject, the argument must
implement the IUIComponent interface
to be added as a child of a container.
All Flex components implement this
interface.
Sprite does not implement IUIComponent, so you are experiencing a pretty typical issue. UIComponent's don't typically have speed issues when compared to Sprites, so I would recommend just drawing on your UIComponent.
As stated before, you /could/ extend Sprite to implement IUIComponent, but it's a pain.
Hope this helps!

Flex/AS3: changing width/height doesn't affect contents

I thought I had a handle on AS3, DisplayObjectContainers, etc. but this basic thing is really confusing me: changing the width/height of a sprite does not affect it's visual contents - either graphics drawn within it or any children it may have.
I have searched around and found an Adobe page that represents my own little test code. From that page, I would expect the sprite to increase in visual size as it's width increases. For me, it doesn't. (http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/display/DisplayObject.html#width)
width property
width:Number [read-write]
Indicates the width of the display object, in pixels. The width is calculated based on the bounds of the content of the display object. When you set the width property, the scaleX property is adjusted accordingly, as shown in the following code:
My code below doesn't affect the visual display at all - but it does set the width/height, at least according to the trace output. It does not affect the scaleX/scaleY.
What the heck am I missing here??
My setup code:
testSprite = new SpriteVisualElement();
var childSprite:SpriteVisualElement = new SpriteVisualElement();
childSprite.graphics.beginFill(0xFFFF00, 1);
childSprite.graphics.drawRect(0, 0, 200, 100);
childSprite.graphics.endFill();
childSprite.name = "child";
testSprite.addChild(childSprite);
container.addElement(testSprite);
testSprite.addEventListener(MouseEvent.CLICK, grow);
}
public function grow(event:MouseEvent):void
{
event.target.width += 5;
event.target.height += 5;
trace("grow", event.target.width);
}
If I understand the code correctly; you are changing the width / height of the sprite. But you are doing nothing to change the width/ height of the sprite's children.
In the context of a Flex Application, you can use percentageWidth and percentageHeight on the child to resize the child when the parent is resized. You could also add a listener to the the resize event and adjust sizing that way; preferably tying in to the Flex Component LifeCycle methods somehow.
I believe these approaches are all Flex specific, and dependent upon the Flex Framework. Generic Sprites, as best I understand, do not automatically size themselves to percentages of their parent container; and changing the parent will not automatically resize the parent's children.
I bet something like this would work:
public function grow(event:MouseEvent):void
{
event.target.width += 5;
event.target.height += 5;
childSprite.width += 5;
childSprite.height += 5;
trace("grow", event.target.width);
}
First, if you have a problem with a flex component, you can look over its source code.
In my environment, (as I installed flex SDK to C:\flex\flex_sdk_4.1), the source code for SpriteVisualElement is located at
C:\flex\flex_sdk_4.1\frameworks\projects\spark\src\spark\core\SpriteVisualElement.as
In the source code, you'll find that width property is overridden :
/**
* #private
*/
override public function set width(value:Number):void
{
// Apply to the current actual size
_width = value;
setActualSize(_width, _height);
// Modify the explicit width
if (_explicitWidth == value)
return;
_explicitWidth = value;
invalidateParentSizeAndDisplayList();
}
So, you cannot expect the auto-scaling of the component.
Making custom components will be one solution.
Here is a sample implementation of custom component.
Custom Component Example - wonderfl build flash online

Flex Datagrid.tooltip with different text styles

I have a tooltip for each datagrid row. Which is fine. I also can style it with with mx:Style which is great.
However, I desire to have multiple styles ie a header and the rest of the text in the tooltip. Is this possible? Or to have htmlText for input?
If you need that you should create your own component implementing mx.core.IToolTip and use it to display the tooltip. Write you own handler for toolTipCreate and in this handler set your own component as the tooltip renderer.
private function createTooltip(e:ToolTipEvent):void {
//CustomToolTip should extend the Canvas and implement IToolTip
var tooltip:CustomToolTip = new CustomToolTip();
//you need to set the tooltip property in order to make your component used for tooltip renderer
e.toolTip = tooltip;
}
<mx:DataGrid id="myDataGrid" toolTip=" " toolTipCreate="createToolTip(event)">

Skinned Panel content offset in Flex 3

Here is the problem. I've created custom RectangularBorder and set it as border skin for TitleWindow. After this manipulation inner content of window is starting at 0,0 point of it. How could I set offset of it?
Just setting top padding does not work because scroll bar still begins from the top of the window after this manipulation.
There are lots of problems with trying to skin panels in Flex 3, and TitleWindow inherits from Panel.
This is the best explanation I've seen. (I'm not the same Glenn referenced in the italics :)).
For programmatic skin it went out pretty simple. One should override function get borderMetrics to do so:
public override function get borderMetrics():EdgeMetrics
{
var borderThickness:Number = getStyle("borderThickness");
var cornerRadius:Number = getStyle("cornerRadius");
var headerHeight:Number = getStyle("headerHeight");
return new EdgeMetrics(
borderThickness,
borderThickness + headerHeight,
borderThickness,
borderThickness);
}
try to use padding-top , padding-left etc as a style for your TitleWindow

How can I change the size of icons in the Tree control in Flex?

I embed SVG graphics in my Flex application using
package MyUI
{
public class Assets
{
[Embed(source="/assets/pic.svg"]
[Bindable]
public static var svgPic:Class;
}
}
and then extending the Tree class with some of my own code, setting the icon upon adding a node to the data provider:
public class MyTree extends Tree
{
public function MyTree()
{
// ...
this.iconField = "svgIcon";
// ...
this.dataProvider = new ArrayCollection;
this.dataProvider.addItem({ /* ... */ svgIcon: MyUI.Assets.svgPic /* ... */ });
// ...
}
}
Now I have two things I want to do:
use the SVG graphics in multiple places in the app, scaling them to the appropriate size for each appearance, i. e. scale them to a proper icon size when using them in the tree
change the size of the icon at runtime, e. g. display a slightly larger icon for selected items or let an icon "pulse" as a response to some event
I read the Flex documentation on the 9-slice scaling properties in the Embed tag, but I think that's not what I want.
Edit:
I unsuccessfully checked the "similar questions" suggested by SO, among others this one:
Flex: Modify an embedded icon and use it in a button?
Subclass mx.controls.treeClasses.TreeItemRenderer and make it resize the icon to your desired dimensions, or create your own item renderer implementation by using the same interfaces as TreeItemRenderer. Set a custom item renderer with the itemRenderer property:
exampleTree.itemRenderer = new ClassFactory( ExampleCustomItemRendererClass );
The answer to this question might point you in the right direction, without knowing more about the trouble you're having:
Flex: Modify an embedded icon and use it in a button?
Hope it helps!

Resources