Actionscript for remove button element - actionscript-3

How can i remove a button in actionscript when we pass that button id.
<fx:Script>
<![CDATA[
public function removebutton(buttonid:String):void
{
hb1.removeElementAt(buttonid);
}
]]>
</fx:Script>
<s:HGroup id="hb1">
</s:HGroup>

As SharpEdge said, there is no public function available to get the element by id, but the work around is:
public function removebutton(buttonid:String):void
{
for (var i:int = 0; i < hb1.numChildren; i++)
{
var object:Object = hb1.getChildAt(i);
if (object.id == buttonid)
{
hb1.removeElementAt(i);
break;
}
}
}

You can use getChildByName(), there is no getElementByID() in Flex.
public function removebutton(buttonid:String):void
{
hb1.removeElement(hb1.getChildByName(buttonid) as IVisualElement);
}

Related

Can't get animation in Custom layout to work

I'd like to create a layout that I can animate my items in. So when a dataprovider gets set on my List, the List's layout will then animate those items onto the screen.
So I've created a CustomLayout and added an update() function.
In the updateDisplayList the items are traced out just fine.
But in the update() function where I want to do the animation, the items are tracing out as null even though if I trace layoutTarget's numElement's I get four! If I use a setTimeout after setting the _dataProvider in my Main app of a second or two, then call update() in the ListLayout, then the traces work fine. So my question is, how can I ensure that I call update() to animate the items in when they are actually available??
Main app:
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:custom="*"
creationComplete="handleCreationComplete()">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
private var _dataProvider:ArrayCollection;
public function set dataProvider(value:ArrayCollection):void
{
_dataProvider = value;
listLayout.update();
}
private function handleCreationComplete():void
{
var arr:Array = new Array( { label:"1" }, { label:"2" }, { label:"3" }, { label:"4" } );
dataProvider = new ArrayCollection(arr);
}
]]>
</fx:Script>
<s:List id="list"
dataProvider="{ _dataProvider }"
labelField="label">
<s:layout>
<custom:ListLayout id="listLayout" />
</s:layout>
</s:List>
</s:WindowedApplication>
ListLayout:
package
{
import mx.core.ILayoutElement;
import spark.components.supportClasses.GroupBase;
import spark.layouts.supportClasses.LayoutBase;
/**
* ...
* #author
*/
public class ListLayout extends LayoutBase
{
public function update():void
{
var layoutTarget:GroupBase = target;
//layoutTarget.autoLayout = false;
var count:int = layoutTarget.numElements;
trace(count); //traces 4
for (var i:int = 0; i < count; i++)
{
var item:ILayoutElement = useVirtualLayout ? layoutTarget.getVirtualElementAt(i) : layoutTarget.getElementAt(i);
trace(item); //traces null
}
}
override public function updateDisplayList(width:Number, height:Number):void
{
super.updateDisplayList(width, height);
var layoutTarget:GroupBase = target;
var count:int = layoutTarget.numElements;
for (var i:int = 0; i < count; i++)
{
var item:ILayoutElement = useVirtualLayout ? layoutTarget.getVirtualElementAt(i) : layoutTarget.getElementAt(i);
trace(item); //traces out the item
}
}
}
}
Before you call update on your listLayout, you need to validate your "list" to make sure all the elements are available. So add one line list.validateNow() in set dataProvider function as below:
public function set dataProvider(value:ArrayCollection):void
{
_dataProvider = value;
list.validateNow();
listLayout.update();
}

How to take the information supplied as inputs to the function and save it in a variable?

I am trying to make a game such as concentration for my class. I am having trouble with taking information that is supplied as inputs in a function and saving them to a variable. Here is the working version of what I am trying to do: Working Version
Here is the code from my card component:
<fx:Script>
<![CDATA[
private var _frontFile:String;
private var _backFile:String;
public function makeCard(suit:String, value:String):void
{
_frontFile = "asset/Cards_deck_" + suit + "_" + value + ".jpg";
_backFile = "asset/Cards_back_Jaguar.jpg";
var _suit:String = suit;
var _value:String = value;
}
public function turnUp():void
{
source = _frontFile;
}
public function turnDown():void
{
source = _backFile;
}
public function turnOver():void
{
if (source == _frontFile) {
source = _backFile;
}
else if (source == _backFile) {
source = _frontFile;
}
}
]]>
</fx:Script>
</s:Image>
My main MXML file:
<fx:Style>
#namespace s "library://ns.adobe.com/flex/spark";
#namespace mx "library://ns.adobe.com/flex/mx";
s|Application {
backgroundColor: #006600;
}
#titleLbl {
color: white;
fontSize: 60px;
paddingTop: 15;
}
#infoLbl {
color: yellow;
fontSize: 24px;
}
</fx:Style>
<fx:Script>
<![CDATA[
//Gabe Dougherty
//n222
//1-24-13
import cardGames.*;
private var deck:Deck = new Deck();
private function init():void
{
// Let's exclude the face cards.
deck.makeDeck(false);
deck.shuffle();
// Deal the cards.
var cardCount:int = deck.numCards();
for (var i:int = 0; i < cardCount; i++) {
// Get a card and add it to 'playArea'.
var c:Card = deck.dealCard();
playArea.addElement(c);
// Get the card ready for play.
c.turnDown();
c.addEventListener(MouseEvent.CLICK, chooseCard);
}
}
private function chooseCard(e:MouseEvent):void
{
var card:Card = Card(e.currentTarget);
card.turnUp();
// Report on what type of card.
infoLbl.text = "The card is the " + card.value + " of " + card.suit;
}
]]>
</fx:Script>
<s:Label id="titleLbl" text="Concentration (sort of)"/>
<s:Label id="infoLbl" text="The card is ..."/>
<s:TileGroup id="playArea" requestedRowCount="4"/>
</s:Application>
And then my deck component if needed:
<fx:Script>
<![CDATA[
//set the properties
private var _suitNames:Array = ['clubs', 'diamond', 'heart', 'spade'];
private var _valueNames:Array = ['2', '3', '4', '5', '6', '7', '8', '9', '10'];
private var _faceNames:Array = ['jack', 'queen', 'king', 'ace'];
private var _cards:Array = new Array;
//set the methods
public function dealCard():Card {
return _cards.pop();
}
public function numCards():Number {
return _cards.length;
}
public function shuffle():void {
for (var i:int = 0; i < _cards.length; i++) {
// Take the last card from the deck.
var c:Card = _cards.pop();
// Insert the card back towards the front of the deck, at a random location.
var index:int = Math.random() * (i + 1);
_cards.splice(index, 0, c);
}
}
public function makeDeck(includeFaces:Boolean=true):void {
for each (var suit:String in _suitNames) {
for each (var value:String in _valueNames) {
var card:Card = new Card();
card.makeCard(suit, value);
_cards.push (card);
}
}
if(includeFaces == true){
for each (var suit:String in _suitNames) {
for each (var value:String in _faceNames) {
var card:Card = new Card();
card.makeCard(suit, value);
_cards.push (card);
}
}
}
}
]]>
</fx:Script>
</fx:Object>
If you declare a variable inside a function then its scope is local to that function. You can't use it outside the function--it doesn't exist.
So you'll need to move those declarations for _suit and _value outside of the makeCard function if you want them to be accessible by the rest of the class:
private var _frontFile:String;
private var _backFile:String;
private var _suit:String;
private var _value:String
public function makeCard(suit:String, value:String):void {
_frontFile = "asset/Cards_deck_" + suit + "_" + value + ".jpg";
_backFile = "asset/Cards_back_Jaguar.jpg";
_suit = suit;
_value = value;
}
But...
Since those are private variables, you won't be able to access them from outside the Card class. You could just make them public variables, but a more flexible way is to add accessor methods to the class. These are public functions that let other classes access the values:
public function get suit():String {
return _suit;
}
public function get value():String {
return _value;
}
Now your program should work.
If you need to be able to change those values from outside the Card class, you'll need to write public 'setter' methods to modify the values of the private variables.

rummy card placement on canvas

I am trying to place 5 cards overlapping 30% on one another. and trying to give a movement to it using mouse events . It should drop within the 5 cards only, not outside of that.
I have learned the drag and drop events and executed it, but i cannot place the card within the 5 cards .
Please somebody help me in this. Please Check the Below Code:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="carcan();">
<mx:Script>
<![CDATA[
import mx.containers.Canvas;
import mx.controls.Image;
private var images:Array;
private var images1:Array;
private const IMAGE_COUNT:uint = 5;
private var img:Image;
private var img1:Image;
private var points:flash.geom.Point;
private var offset_x:int;
private var offset_y:int;
private var canal:Canvas;
private var doDrag:Boolean;
[Embed(source='cards/2C.png')]
private var Image0:Class;
[Embed(source='cards/2D.png')]
private var Image1:Class;
[Embed(source='cards/2H.png')]
private var Image2:Class;
[Embed(source='cards/2S.png')]
private var Image3:Class;
[Embed(source='cards/3C.png')]
private var Image4:Class;
public function carcan():void
{
canal = new Canvas();
canal.setStyle("backgroundColor","blue");
canal.x=100;
canal.y=50;
canal.width=500;
canal.height=400;
this.addChild(canal);
init();
}
public function init():void
{
images = new Array(IMAGE_COUNT);
for (var i:int = 0; i < IMAGE_COUNT; i++)
{
img= new Image();
img1= new Image();
images[i] = this["Image" + i];
trace(images[i]);
img.x=(i*30)+50;
img.source=images[i];
img.id="Image"+i;
canal.addChild(img);
img.addEventListener(MouseEvent.MOUSE_DOWN, md);
img.addEventListener(MouseEvent.MOUSE_MOVE, mm);
canal.addEventListener(MouseEvent.MOUSE_OUT,smu);
img.addEventListener(MouseEvent.MOUSE_UP, mu);
}
}
public function smu(event:MouseEvent):void
{
img.alpha=1;
img.stopDrag();
doDrag=false;
setCards();
}
public function mo(event:MouseEvent):void
{
if(doDrag==true)
{
img.addEventListener(MouseEvent.MOUSE_DOWN, md);
img.addEventListener(MouseEvent.MOUSE_UP, mu);
img.stopDrag();
img.alpha=1;
img.removeEventListener(MouseEvent.MOUSE_MOVE, mm);
}
else
{
img.addEventListener(MouseEvent.MOUSE_MOVE, mm);
}
}
public function md(event:MouseEvent):void
{
img = new Image();
doDrag=true;
canal.setChildIndex(Image(event.target),images.length-1);
img.addEventListener(MouseEvent.MOUSE_MOVE, mm);
}
public function mm(event:MouseEvent):void
{
if(doDrag==true)
{
points = new Point();
images = new Array(IMAGE_COUNT);
img = new Image();
img = Image(event.target);
points.x=event.target.x;
points.y=event.target.y;
points = localToGlobal(points);
img.x=points.x;
img.y=points.y;
img.alpha=0.7;
img.addEventListener(MouseEvent.MOUSE_UP, mu);
var boundar:flash.geom.Rectangle = new Rectangle(this.x, this.y, 250, 100);
}
}
public function mu(event:MouseEvent):void
{
img.alpha=1;
canal.stopDrag();
doDrag=false;
canal.stopDrag();
doDrag=false;
var current:Image = event.currentTarget as Image;
var num1:int = current.x;
if(num1 < 50){
canal.setChildIndex(current, images.length-5);
current.y=0;
setCards();
}
if(num1 > 50 && num1 < 80){
canal.setChildIndex(current, images.length-4);
current.y=0;
setCards();
}
if(num1 > 80 && num1 < 110){
canal.setChildIndex(current, images.length-3);
current.y=0;
setCards();
}
if(num1 > 110 && num1 < 140){
canal.setChildIndex(current, images.length-2);
current.y=0;
setCards();
}
if(num1 > 140 && num1 < 170){
canal.setChildIndex(current, images.length-2);
current.y=0;
setCards();
}
if(num1 > 170){
canal.setChildIndex(current, images.length-1);
current.y=0;
setCards();
}
}
private function setCards():void{
var b:int = 0;
var a:int;
var cardsArray:Array = canal.getChildren();
for(a = 0;a < cardsArray.length; a++)
{
canal.getChildAt(a).x = 50+b;
b=b+30;
canal.getChildAt(a).y=0;
}
}
]]>
</mx:Script>
</mx:Application>
PS: I am trying to replace the drag and drop events with mouse events and get the same functionality using mouse events. Please somebody help me in this.
Hope Below Code may help you: - You can use Drag and drop as per below code and create it in AS. I have created it in MXML which will give you some idea what you are looking for: -
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" xmlns:local="*">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.core.DragSource;
import mx.core.UIComponent;
import mx.events.DragEvent;
import mx.managers.DragManager;
private function doDragEnter(event:DragEvent):void
{
DragManager.acceptDragDrop(UIComponent(event.target));
}
private function doDragDrop(event:DragEvent):void
{
var img:RummyItemRenderer;
if (event.dragInitiator.parent == mainCanvas)
{
img = event.dragInitiator as RummyItemRenderer;
//mainCanvas.swapChildren(img, event.currentTarget as RummyItemRenderer);
var index:Number = mainCanvas.getChildIndex(event.currentTarget as RummyItemRenderer);
mainCanvas.removeChild(img);
mainCanvas.addChildAt(img,index);
setCardsPosition();
}
}
private function setCardsPosition():void{
var b:int = 0;
var a:int;
var cardsArray:Array = mainCanvas.getChildren();
for(a = 0;a < cardsArray.length; a++)
{
mainCanvas.getChildAt(a).x = 50+b;
b = b+30;
mainCanvas.getChildAt(a).y=20;
}
}
private function doDragStart(event:MouseEvent):void
{
var dragInitiator:RummyItemRenderer = event.currentTarget as RummyItemRenderer;
var dragSource:DragSource = new DragSource();
DragManager.doDrag(dragInitiator, dragSource, event);
}
]]>
</fx:Script>
<mx:Canvas id="mainCanvas" backgroundColor="#DDDDDD" width="400" height="200" x="50" y="50">
<local:RummyItemRenderer id="firstID" x="{mainCanvas.x}" y="20" width="200" height="80%" backgroundColor="#FF0000"
mouseDown="doDragStart(event)" dragEnter="doDragEnter(event)" dragDrop="doDragDrop(event)"
setImageSource="myImageURL"/>
<local:RummyItemRenderer id="secondID" x="{mainCanvas.x + 30}" y="20" width="200" height="80%" backgroundColor="#00FF00"
mouseDown="doDragStart(event)" dragEnter="doDragEnter(event)" dragDrop="doDragDrop(event)"
setImageSource="myImageURL"/>
<local:RummyItemRenderer id="thirdID" x="{mainCanvas.x + 60}" y="20" width="200" height="80%" backgroundColor="#0000FF"
mouseDown="doDragStart(event)" dragEnter="doDragEnter(event)" dragDrop="doDragDrop(event)"
setImageSource="myImageURL"/>
</mx:Canvas>
</s:Application>
RummyItemRenderer.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="100%" height="100%">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
[Bindable]
private var _setImageSource:String;
public function get setImageSource():String
{
return _setImageSource;
}
public function set setImageSource(sourceURL:String):void
{
_setImageSource = sourceURL;
}
]]>
</fx:Script>
<s:Image id="imageID" source="{_setImageSource}"/>
</mx:Canvas>

The card is moving in vertical direction, as i am trying to get that in horizontal movement

I am just trying to make an image move within specified canvas area. If the mouse cursor is moved out of the canvas area, the image should get back to original position. below is the code i have tried.
<mx:Script>
<![CDATA[
import mx.controls.Image;
import mx.containers.Canvas;
import flash.geom.Rectangle;
/* [Embed(source="cards/2C.png")]
private var pic:Class; */
public var points:Point;
public var clan:Canvas;
public var offset_x:int;
public var offset_y:int;
public var dropIndex:int=-1;
public var img:Image;
public var dragImage:Image;
public var myImage:Image;
public var doDrag:Boolean;
public var acceptDrag:Boolean;
public function init():void
{
myImage = new Image();
clan = new Canvas();
clan.width=400;
clan.height=300;
clan.x=200;
clan.y=150;
clan.setStyle("backgroundColor",0xcfdccc);
addChild(clan);
myImage.source= pic.pic1;
clan.addChild(myImage);
myImage.addEventListener(MouseEvent.MOUSE_DOWN, ondown);
myImage.addEventListener(MouseEvent.MOUSE_MOVE, mm);
}
public function ondown(event:MouseEvent):void
{
doDrag=true;
return;
}
public function mm(event:MouseEvent):void
{
if(doDrag==true)
{
points = new Point();
myImage.source=event.target.source;
points.x=event.target.x;
points.y=event.target.y;
points=localToGlobal(points);
dragImage = mx.controls.Image(event.target);
myImage.x=points.x;
myImage.y=points.y;
trace(points);
var mywidth:int=clan.width-myImage.width;
var myheight:int=clan.height-myImage.height;
var boundar:flash.geom.Rectangle=new Rectangle(offset_x, offset_y ,mywidth,myheight);
myImage.startDrag(false, boundar);
myImage.addEventListener(MouseEvent.MOUSE_MOVE, onmove);
myImage.addEventListener(MouseEvent.CLICK, onup);
event.updateAfterEvent();
}
}
public function onmove(event:MouseEvent):void
{
if(doDrag)
{
// myImage = new Image();
clan = new Canvas();
var diff:Number = NaN;
var doIncrement:Boolean=false;
var point2:flash.geom.Point= new Point();
img=mx.controls.Image(event.target);
point2.x=this.x;
point2.y=this.y;
point2=globalToLocal(point2);
trace("point2="+ point2);
diff=points.x;
/* trace(stage.x);
trace(stage.y); */
points.x=img.x;
points.y=img.y;
points=globalToLocal(points);
diff=points.x;
trace("points.x="+points.x);
trace("diff: "+ diff);
trace("dropIndex: "+ dropIndex);
if(diff >=0)
{
dropIndex=Math.floor(points.x / offset_x);
doIncrement=true;
trace("dropIndex1: "+ dropIndex);
}
else
{
dropIndex=Math.floor(points.x / offset_x);
}
if(doIncrement)
{
dropIndex++;
}
if(dropIndex >= 0)
{
acceptDrag = true;
}
else if (dropIndex >= -5 && dropIndex <= -1)
{
dropIndex = 0;
acceptDrag = true;
}
}
}
public function onup(event:MouseEvent):void
{
doDrag=false;
img.stopDrag();
acceptDrag=false;
}
]]>
</mx:Script>
If I am understanding your question correctly, I believe you are making it much more complicated than it needs to be. Adding a MouseEvent.ROLL_OUT event listener to the Canvas and then resetting the image to it's original coordinates should result in the behavior you are looking for. Here is a quick and dirty version I tested that you can use, expand on, or borrow from:
<fx:Script>
<![CDATA[
private var offset_x:int;
private var offset_y:int;
/**
* Calibrates the drag operation so that they ghosted image follows the cursor based on
* where the image was clicked. It then makes the ghosted image visible and
* attaches the MOUSE_MOVE handler so that it will begin tracking.
**/
private function myImageMouseDownHandler(event:MouseEvent):void {
offset_x = myImage.mouseX;
offset_y = myImage.mouseY;
dragImage.visible = true;
clan.addEventListener(MouseEvent.MOUSE_MOVE, onDrag);
}
/**
* Calls the cleanup function then resets the ghosted image for further use.
**/
private function clanRolloutHandler(event:MouseEvent):void {
dragCleanup();
dragImage.x = myImage.x;
dragImage.y = myImage.y;
}
/**
* Calls the cleanup function then sets the main Image to the ghosted image's location.
**/
private function endDrag(event:MouseEvent):void {
dragCleanup();
myImage.x = dragImage.x;
myImage.y = dragImage.y;
}
/**
* Sets the ghosted image to follow the mouse cursor offset by the location of the
* original click.
**/
private function onDrag(event:MouseEvent):void {
dragImage.x = clan.mouseX - offset_x;
dragImage.y = clan.mouseY - offset_y;
}
/**
* Hides the ghosted image and removes the MOUSE_MOVE event handler so that the function
* is no longer called.
**/
private function dragCleanup():void {
dragImage.visible = false;
clan.removeEventListener(MouseEvent.MOUSE_MOVE, onDrag);
}
]]>
</fx:Script>
<mx:Canvas id="clan" rollOut="clanRolloutHandler(event)" mouseUp="endDrag(event)" horizontalScrollPolicy="off" verticalScrollPolicy="off"
top="150" left="200" width="400" height="300" backgroundColor="#CFDCCC">
<mx:Image id="myImage" mouseDown="myImageMouseDownHandler(event)"
source="http://www.leadersinstitute.com/wp-content/uploads/2011/02/playing-cards.jpg" height="50" width="50"/>
<mx:Image id="dragImage" alpha="0.5" visible="false"
source="http://www.leadersinstitute.com/wp-content/uploads/2011/02/playing-cards.jpg" height="50" width="50"/>
</mx:Canvas>
MouseEvent.MOUSE_LEAVE will trigger when the mouse completely leaves the flash window, you could try resetting the images position when this happens and use MouseEvent.MOUSE_ENTER to start tracking again, when required.
This should help: http://www.kirupa.com/developer/flashcs3/detecting_when_mouse_leaves_movie.htm

How can I get a mx:textarea height to be the same as the content

The initial height of a text area is much larger than the content, I cannot find a way of making it always the same height as the text content:
<mx:TextArea id="textarea" borderStyle="solid" width="100%" wordWrap="true" selectable="false" backgroundAlpha="0" focusAlpha="0" text="this is a little test" />
Gives a bordered box that is much taller than needed.
This also gives an unintential problem if you have links within the content in that a link 'mouseover' is triggered when nowhere near the link.
<mx:Script>
<![CDATA[
public function onInit():void
{
var style:StyleSheet = new StyleSheet();
var aLink:Object = new Object();
aLink.color = "#0000FF";
var aHover:Object = new Object();
aHover.color = "#00FF00";
aHover.textDecoration = "underline";
style.setStyle( "a:hover", aHover );
style.setStyle( "a:link", aLink );
textarea.styleSheet = style;
}
]]>
</mx:Script>
<mx:TextArea id="textarea" width="100%" wordWrap="true" borderStyle="solid" selectable="false" backgroundAlpha="0" focusAlpha="0" >
<mx:htmlText>
<![CDATA[<a href='event:http://www.adobe.com'>Navigate to Adobe.com.</a> this is testing nothing at all really]]>
</mx:htmlText>
</mx:TextArea>
The Text component doesnt suffer from this, but I cannot attach a stylesheet to a text component.
Hoping someone can help. Or is there some other component I can use where I can add a stylesheet to stylise anchor tags.
I found this overridable in the TextArea.as source and if I override it and remove the "2 x" multiplier it almost works but unfortunately it means that the content doesnt get bigger when it needs to and vertically scrolls instead, so its almost there:
override protected function measure():void
{
super.measure();
measuredMinWidth = DEFAULT_MEASURED_MIN_WIDTH;
measuredWidth = DEFAULT_MEASURED_WIDTH;
// TextArea is minimum of two lines of text
measuredMinHeight = measuredHeight = 2 * DEFAULT_MEASURED_MIN_HEIGHT;
}
If you extend Text, you can add a getter/setter that allows you to set the styleSheet of the underlying UITextField object.
package
{
import flash.events.Event;
import flash.text.StyleSheet;
import mx.controls.Text;
import mx.core.mx_internal;
use namespace mx_internal;
public class StyledText extends Text
{
public function StyledText()
{
super();
}
private var _styleSheet:StyleSheet = null;
[Bindable("stylesheetChanged")]
public function get styleSheet():StyleSheet {
return _styleSheet;
}
public function set styleSheet(value:StyleSheet):void {
_styleSheet = value;
if ( textField ) {
textField.styleSheet = _styleSheet;
}
dispatchEvent(new Event("stylesheetChanged"));
}
override protected function createChildren():void {
super.createChildren();
//textField is created in the createChildren
//method of the Label class
if ( textField && styleSheet ) {
textField.styleSheet = _styleSheet;
}
}
}
}
Then you can use the component like so:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:ns1="*" preinitialize="onInit()">
<mx:Script>
<![CDATA[
public function onInit():void
{
var style:StyleSheet = new StyleSheet();
var aLink:Object = new Object();
aLink.color = "#0000FF";
var aHover:Object = new Object();
aHover.color = "#00FF00";
aHover.textDecoration = "underline";
style.setStyle( "a:hover", aHover );
style.setStyle( "a:link", aLink );
text.styleSheet = style;
}
]]>
</mx:Script>
<ns1:StyledText id="text" x="0" y="79">
<ns1:htmlText>
<![CDATA[<a href='event:http://www.adobe.com'>Navigate to Adobe.com.</a> this is testing nothing at all really]]>
</ns1:htmlText>
</ns1:StyledText>
</mx:Application>
I haven't tried what you're attempting, but this link looks like it might help:
http://www.adobe.com/cfusion/communityengine/index.cfm?event=showdetails&postId=13628&productId=2.
Based on Bedwyr's link, I thought I would try recalcing the height myself and this seems to work fine (not noticed any bad side-effects yet, but there may be):
this.addEventListener( Event.CHANGE, onReMeasure );
this.addEventListener( Event.RESIZE, onReMeasure );
override protected function measure():void
{
super.measure();
measuredMinWidth = DEFAULT_MEASURED_MIN_WIDTH;
measuredWidth = DEFAULT_MEASURED_WIDTH;
var lm:TextLineMetrics = getLineMetrics( 0 );
measuredMinHeight = measuredHeight = DEFAULT_MEASURED_MIN_HEIGHT;
}
private function onReMeasure( eventObj:Event ):void
{
var ht:Number = 0;
for( var n:int = 0; n < textField.numLines; n++ )
{
ht += textField.getLineMetrics(n).height;
}
ht += 10; // padding
height = ht;
validateNow();
}