Flex: X-out Label? - apache-flex

I am trying to make a label that has an X over it. Like so I can say was this price with an X over the price. I want to make it a component because I am going to use it more than once. I want the X to be close to the same size as the text so that it is not a giant X over small text or a small X over large text.
Here is the code I tried which did nothing at all:
<?xml version="1.0" encoding="utf-8"?>
<mx:Label xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
override public function set text(value:String):void
{
super.text = value;
var g:Graphics = this.graphics;
g.clear();
g.lineStyle(3,0xFF0000);
g.lineTo(this.width,this.height);
g.moveTo(0,this.height);
g.lineTo(this.width,0);
}
]]>
</mx:Script>
</mx:Label>

See this post. It provides a component which will do this for you.
It's not currently supported natively.

Related

Flex: rounded corners for dynamic created images

there a better way as this example
to create round corners for dynamic (addChild or addElement) created Images?
ok, here is a custom class http://santobay.blogspot.com/2010/04/rounded-corner-image-in-flex.html . save this code as com/RoundedImage.as , create new mxml file with this code
<mx:Application name="Image_mask_test"
xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:custom="com.*"
layout="vertical"
verticalAlign="middle"
backgroundColor="white">
<mx:HBox id="hbox" width="100%">
<custom:RoundedImage source="images/test.jpg" width="250" height="250" cornerRadius="15"/>
</mx:HBox></mx:Application>
and compile. For create images dynamic use this code:
<fx:Script>
<![CDATA[
import com.RoundedImage;
public function createImage():void {
var newImage:RoundedImage = new RoundedImage();
newImage.source = "images/test.jpg";
newImage.cornerRadius = 20;
hbox.addChild(newImage);
}
]]>
</fx:Script>
No, you must use a mask, if you add it dynamically.
However, you could add a 'frame' on top of the image, if the background is solid, you can use this trick.

Spark TextArea or RichText autosize

I have done lots of searching on this subject, but it seems what I am finding is either out of date or just does not seem to work.
With TextFields in the past, you could set the TextField to a certain width, set wordWrap to true and you would end up with a textfield that changed height according to the text you added.
Now I am trying to do this with either the Spark TextArea or RichText.
I tried this HeightInLines = NAN, but that seems to be out of date.
I also tried this routine:
var totalHeight:uint = 10;
this.validateNow();
var noOfLines:int = this.mx_internal::getTextField().numLines;
for (var i:int = 0; i < noOfLines; i++)
{
var textLineHeight:int =
this.mx_internal::getTextField().getLineMetrics(i).height;
totalHeight += textLineHeight;
}
this.height = totalHeight;
But the mx_internal is not in the Spark components.
I am trying to do this with AS3, not MXML. If anyone has any suggestions or links that could help me figure this out using AS3, I'd really appreciate it.
Been struggling with this all afternoon. But it looks like the RichEditableText component will autosize if you set its width and leave its height undefined.
This works fine:
<?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">
<s:TextArea updateComplete="event.currentTarget.heightInLines = NaN" />
</s:Application>
Found in comments here. You can do the same in ActionScript using the same updateComplete event.
This is how I set the height of a TextArea to fit its content when used inside an ItemRenderer (e.g. for a List component):
private function onUpdateComplete( e: Event ): void
{
// autoresize the text area
if ( theText ) {
var actualNumOfLines: int = theText.textFlow.flowComposer.numLines;
theText.heightInLines = actualNumOfLines;
invalidateSize();
}
}
ItemRenderer must have this property set:
<s:ItemRenderer ... updateComplete="onUpdateComplete(event)>
Maybe the updateComplete event is not the optimal trigger for auto-resize actions but works fine for me.
You can remove scrollers from TextArea's skin and it becomes autoresizable. You can download completed skin here: http://www.yumasoft.com/node/126
Here's a solution for spark text areas (it works as mx text areas do):
var ta_height:int;
for(var i:int=0; i < StyleableTextField(myTextArea.textDisplay).numLines; i++) {
ta_height += StyleableTextField(myTextArea.textDisplay).getLineMetrics(i).height;
}
myTextArea.height = ta_height;
This seems to work for me:
<s:TextArea id="testTextArea"
change="testTextArea_changeHandler(event)"
updateComplete="testTextArea_updateCompleteHandler(event)"/>
<fx:Script>
<![CDATA[
protected function testTextArea_changeHandler(event:TextOperationEvent):void
{
testTextArea.height = RichEditableText(testTextArea.textDisplay).contentHeight + 2;
}
protected function testTextArea_updateCompleteHandler(event:FlexEvent):void
{
testTextArea.height = RichEditableText(testTextArea.textDisplay).contentHeight + 2;
}
]]>
</fx:Script>
Been doing the same head banging over that s:TextArea, and then found out that this gets the job done :
<s:RichEditableText id="txtArea" left="0" right="0" backgroundColor="#F7F2F2"
change="textChanged()" />

how to apply tween motion on UIcomponents in flex using actionscript?

hello i want to apply tween motion on UIcomponents using actionscript in flex.
i searched alot but didn't find something useful help required.
thanks in advance.
The code below creates a move tween for a button in actionscript.
Clicking anywhere on the screen will move the button to that location.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" click="moveButton(event)">
<mx:Script>
<![CDATA[
import mx.effects.Move;
private function moveButton(event:MouseEvent):void {
var myMove:Move = new Move();
myMove.target = myButton;
myMove.xTo = event.stageX;
myMove.yTo = event.stageY;
myMove.play();
}
]]>
</mx:Script>
<mx:Button id="myButton" />
</mx:Application>
For a more advanced example you could look at the Flex documentation: http://livedocs.adobe.com/flex/3/html/help.html?content=createeffects_3.html
It shows an example how to extend and use the TweenEffect class to create your own effect class.
Caurina Tweener: http://code.google.com/p/tweener/

Cropping/Clipping A Sprite

How is cropping/clipping accomplished on a Sprite in Flex?
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" creationComplete="Init()">
<mx:Script>
<![CDATA[
public function Init():void {
var spr:Sprite=new Sprite();
uic.addChild(spr);
uic.graphics.lineStyle(2,0);
uic.graphics.moveTo(22, 22);
uic.graphics.lineTo(2222, 2222);
}
]]>
</mx:Script>
<mx:Panel title="StackOverflow">
<mx:UIComponent width="200" height="200" id="uic"/>
</mx:Panel>
</mx:WindowedApplication>
Notice that the lineTo completely leaves the UIComponent and Panel.
How can I cause my UIComponent or Sprite, Or Panel for that matter, to be cropped/clipped?
(source: liquidfeline.com)
I realize I could just change the hard-coded 2222's to something more reasonable, but I need a generalized solution to this, since the actual project doesn't involve hard-coded values that I can alter, but works with dynamic data.
You should also try using scrollRect, this will be faster in performance than a mask. Introduction to the scrollRect from Grant Skinner.
Use a mask.
var mask:Shape = new Shape();
with(mask.graphics)
{
beginFill(0xFFFFFF, 1); // white, opaque
drawRect(0, 0, width, height);
endFill();
}
uic.mask = mask;

Not include component size in measure

I have a custom component that is basically a VBox with a Label and a TextField.
<mx:VBox width="50%">
<mx:Label width="100%"/>
<mx:TextField width="100%"/>
</mx:VBox>
What I want, basically, is to have two of these VBoxes layed out on a HBox and each would take exactly 50% - their children Label and TextField should just obey that.
If I set both Label and TextField's width to 100%, and the Label text doesn't fit, the default behaviour is to expands the VBox width - I don't want that to happen. The TextField should always take 100% of the width, and I'd want the Label to be explicitly set to the width of the TextField, so the text would be truncated and not expand the VBox width.
Is there a way to tell the Label to just obey the VBox (or TextField) width and not be included in the measurement of the VBox width?
Not sure if I was clear. :)
Thanks in advance.
it wasn't that easy as I thought. At the beginning I wanted to suggest maxWidth but it doesn't work correctly with label. However I just tested this:
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.controls.TextInput;
import mx.controls.Label;
private function onTextChanged(event:Event):void {
var currentText:String = TextInput(event.target).text;
var shortened:Boolean = false;
// adding 30 to leave some space for ...
while ( lbl.measureText(currentText).width > (lbl.width-30) ) {
currentText = currentText.substr(0,currentText.length-1);
shortened = true;
}
lbl.text = currentText + ((shortened) ? "..." : "" );
}
]]>
</mx:Script>
<mx:VBox width="50%">
<mx:Label id="lbl" width="100%" />
<mx:TextInput width="100%" change="onTextChanged(event);" />
</mx:VBox>
</mx:WindowedApplication>
It probably isn't written in a way (just attributed) you expected but it does what you need.
If this isn't a solution you could think of extending the Label in the following manner.
Crete custom Label:
radekg/MyLabel.as
package radekg {
import mx.controls.Label;
public class MyLabel extends Label {
public function MyLabel() {
super();
}
private var _myText:String;
override public function get text():String {
return _myText;
}
override public function set text(value:String):void {
if ( value != null && initialized ) {
// store the copy so the getter returns original text
_myText = value;
// shorten:
var shortened:Boolean = false;
while ( measureText(value).width > (width-30) ) {
value = value.substr(0,value.length-1);
shortened = true;
}
super.text = value + ((shortened) ? "..." : "");
}
}
}
}
And use it like that:
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:controls="radekg.*">
<mx:VBox width="50%">
<controls:MyLabel width="100%" id="lbl" text="{ti.text}" />
<mx:TextInput width="100%" id="ti" />
<mx:Button label="Display label text" click="mx.controls.Alert.show(lbl.text)" />
</mx:VBox>
</mx:WindowedApplication>
This can be used simply with binding. Once you type very long text into the text input and the Label displays ... click on the button. You'll notice that text() getter returns original text.
Hope this helps.

Resources