textbox autoresizing in actionscript3 - actionscript-3

I need to realize textbox autoresizing in actionscript3(IDE - adobe flash pro cs3). For example my textarea is in width 100 px, user has been wrote in it something, that is bigger than 100 px, then my textbox should become increasingly. any ideas?
Also I can't realize multiline option: when the text goes beyond the textbox, it starts to scroll. In line type I've chosen 'multiline'.
thanks

try this:
textfield.autoSize = "left";
textfield.multiline = true;
textfield.wordWrap = true;
Hope it helps,
Rob

If you want to resize textfield automaticaly you can use textfield.autoSize property.
Wnen you are using multiline textfield, then setting
textfield.autoSize = TextFieldAutoSize.LEFT;
will align text to left and resize field vertically. If you use single line text field, it will resize to the right.

The TextField's .autosize property is great for sizing dynamic text fields when you already know the text string (but mind the .multiline and .wordwrap properties), but won't be helpful for input text fields.
For input text, I'd suggest listening for the Event.CHANGE event, then updating the width/height based on the number of lines, the .textWidth, or TextLineMetrics info (e.g. myTextField.getLineMetrics).
Here's a quick example:
var myField:TextField = new TextField();
myField.x = 10;
myField.y = 10;
myField.width = 100;
myField.height = 20;
myField.border = true;
myField.type = TextFieldType.INPUT;
myField.addEventListener(Event.CHANGE, textChangeHandler);
addChild(myField);
function textChangeHandler(evt:Event) {
var buffer:Number = 10;
myField.width = Math.max(100, (myField.textWidth + buffer));
myField.scrollH = 0;
}
Edit: Oh, and if you want that to work with .multiline, then just add:
myField.multiline = true;
and in the textChangeHandler function add:
myField.height = myField.textHeight + buffer;

Related

tlfTextField - Highlight a part of text with "Code"

I wonder how to set the text "Highlight" of a part of text inside tlfTextField with the code?
I tried "tf.backgroundColor = 0x990000" property, but did not help.
For instance, I can change the Font Color of any contents inside Parenthesis, by this code:
private function decorate():void {
var tf:TextFormat = new TextFormat();
tf.color = 0x990000;
var startPoint:int = 0;
while (startPoint != -1) {
var n1:int = textMc.tlfText.text.indexOf("(", startPoint);
var n2:int = textMc.tlfText.text.indexOf(")", n1 + 1);
if (n1 == -1 || n2 == -1) {
return;
}
textMc.tlfText.setTextFormat(tf, n1 + 1, n2);
startPoint = n2 + 1;
}
}
So I know "tf.color = 0x990000;" will change the Font color, however, don't know how to "highlight" some text, with code, as I do inside Flash manually.
You should have probably used tlfMarkup property to set the required format to the specific part of text. The attributes you seek are backgroundColor and backgroundAlpha of the span XML element that you should wrap your selection, however it should be much more difficult should there already be spans around words when you retrieve the property from your text field.
The problem with your solution is that you don't check if the two characters are located on a single line before drawing your rectangle, also you would need to redraw such rectangles each time something happens with the textfield. The proposed approach makes use of Flash HTML renderer's capabilities to preserve the formatting, however it will require a lot of work to handle this task properly.

How to create a button that makes a new text field appear on screen?

I've been having trouble getting this button to work. I want it so that whenever you click it, a new text field pops up that you can type stuff in. This is supposed to be for a trivia-like game, where the user inputs their own questions and answers. Here's the code so far...
This is the text field's properties -
QuestionTextField = new TextField();
QuestionTextField.defaultTextFormat = SmallTextFormat;
QuestionTextField.textColor = 0x660000;
QuestionTextField.x = stage.stageWidth * 0.1;
QuestionTextField.y = 200;
QuestionTextField.width = stage.stageWidth * 0.8;
QuestionTextField.height = 20;
QuestionTextField.selectable = false;
QuestionTextField.type = TextFieldType.INPUT;
QuestionTextField.border = true;
QuestionTextField.multiline = true;
QuestionTextField.wordWrap = true;
And this is the function that is supposed to create a new text field every time the button is clicked-
private function AddQuestionButtonClicked(m:MouseEvent){
for(var i = Questions.length; i>=1; i--){
container_buttonsMC.addChild(QuestionTextField);
Questions.push(QuestionTextField);
QuestionTextField.y += 20
}
}
Notes : "Questions" is an array that holds the number of text fields there are, container_buttonsMC holds all of the buttons on that are on the game's main menu.
The problem is that whenever I click it, it 1. Doesn't actually create a new text field, but instead moves it a certain amount of pixels down, and 2. It sort of duplicates the text field's position...if that makes ANY sense at all. If I click on the button once, it will move the text field down by 20 pixels. If I click on it again, it will move it down by 40 pixels, then by 80, and so on...
I also traced the length of the array, and surprisingly enough, the number that appeared would double every time I clicked it. However, only one text field is visible (apparently). It probably has something to do with the for loop's action, but I don't know for sure. Does anyone have an idea as to what the problem is? (Thanks in advance, I'm still new to AS3 and programming in general)
First, each need to create a new textfield every time you click the button, rather than adding it to the stage. With what you have at the moment, you only created one text field.
Secondly, you only want to do add one more text field, right? So instead of using a loop, which will create multiple new text fields, just create one extra text field and add it to the list.
The code will look something like
private function AddQuestionButtonClicked(m:MouseEvent){
var QuestionTextField:TextField = new TextField()
QuestionTextField.defaultTextFormat = SmallTextFormat;
QuestionTextField.textColor = 0x660000;
QuestionTextField.x = stage.stageWidth * 0.1;
QuestionTextField.y = 200;
QuestionTextField.width = stage.stageWidth * 0.8;
QuestionTextField.height = 20;
QuestionTextField.selectable = false;
QuestionTextField.type = TextFieldType.INPUT;
QuestionTextField.border = true;
QuestionTextField.multiline = true;
QuestionTextField.wordWrap = true;
// You can adjust the 50 here to control the spacing between text fields
QuestionTextField.y += 50 * Questions.length
container_buttonsMC.addChild(QuestionTextField);
Questions.push(QuestionTextField);
}

as3 textfield wordwrap true causing textwidth to be weird

I'm trying to wordwrap a textfield inside a button, however after i set wordwrap to true some unexpected behavior happened.
Button.width = 390;
Button.textField.autoSize = TextFieldAutoSize.LEFT;
Button.textField.border = true;
Button.textField.wordwrap = true;
Button.textField.multiline = true;
Button.textField.width = textButton.width - 10;
Button.textField.x = 5;
Button.height = 60;
This is what happens:
When I'm outputting the Button.textField.textWidth, it seems shown a value that so much less than Button or Button.textField.width. I just want to make the word break after textwidth meets the textField.width maximum value. Is there anything that I can do to change this behavior? …since I can't change the value of Button.textField.textWidth (read-only).
Comment out the Button.textField.autoSize setting. This is probably what is throwing everything off.
You're setting the text field's width to match the size of the button when you set width = textButton.width - 10, but you're also telling it to automatically resize the textField to match the size of the actual text when you set the autoSize setting. So it's not going to fit the button the way you want it to.

How to get a RadioButton's label height - AS3

I want to get radioButton's label height in as3.
I have 5 radio buttons in my radioButton group. One of those radioButtons has a three line label, another has a single line etc...
When I try to access the radioButton.height, I always get same value regardless of the label height.
I need to know the height of the label, so I can set the radioButton y coordinate accordingly.
can I change the radioButton's label height?
spacing = 30;
rb.label = tempQQString //from xml. long or short string anyone
rb.group = myGroup;
rb.value = i + 1;
rb.x = answerX;
rb.y = questionField.height + (questionY+20) + (i * spacing); // here use rb.height or rb.textField.height
trace("rb height**" + rb.height) // always get velue 22;
addChild(rb);
RadioButton and any fl control that extends labelButton (all the ones that have a label), expose the actual text field with the .textField property.
So for your example, instead of using rb.height, you would use rb.textField.height to get the height of just the label portion of the control.
You can also set properties on the textField as well.
rb.textField.background = true;
rb.textField.backgroundColor = 0xDDDDDD;
rb.textField.multiline = true;
rb.textField.wordWrap = true;
rb.textField.autoSize = TextFieldAutoSize.LEFT;
now, for your scenario, you may be better off just using the radio button's bounds instead, as it will be the REAL height of the object.
rb.getBounds(rb).height; //this will be the true height of the component.
If your label was one line and your icon was taller than your label, you could potentially be getting a value from rb.textField.height that is smaller than the real height of the radio button.
Try this.
for(var i=0;i<rb.numChildren;i++){
if(rb.getChildAt(i) is TextField){
var txt:TextField = rb.getChildAt(i) as TextField;
trace(txt.height+":"+rb.height);//traces the height of text field and radio button
}
}

Flex container with HTML style floating

I am using Flex 4 with Spark components to build a mobile application and I have a HGroup that I am using to contain all of my elements. When the screen loads it pulls in a small amount of text that will be displayed and loops through all the words to see if any of them are a keyword. While it is looping I am putting each word into its own label element and if the word is a keyword it changes a few styles and adds a click event to show a description about the word.
Everything runs fine but when everything is appended to the HGroup, there ends up being only one line and most of the text completely cut off because it will not wrap the content.
My Question is - Is there a way to set or extend the HGroup to allow content wrapping on its child elements?
Below are some code snippets of what I have:
MXML containers:
<s:VGroup id="answerData" width="580" height="700" horizontalAlign="center" paddingTop="5">
<s:HGroup id="theLabel" color="white" width="580" fontSize="25" paddingBottom="20" />
<s:HGroup id="theText" color="white" width="580" fontSize="25" maxWidth="580" />
</s:VGroup>
AS to create labels:
public static function setKeyWords(someText:String, theGroup:Group, theDictionary:Array, theView:Object):void {
theGroup.removeAllElements();
var textArray:Array = someText.split(' ');
for(var i:int = 0, l:int = textArray.length; i < l; i++) {
if(checkForWord(theDictionary, textArray[i].toString())) {
var theLink:Label = new Label();
theLink.text = textArray[i].toString();
theLink.setStyle("color", "0xFFFF00");
theLink.setStyle("fontWeight", "bold");
theLink.maxWidth = 580;
var tmpDescrip:String = theDescription;
theLink.addEventListener(MouseEvent.CLICK, function(evt:MouseEvent):void {
showToolTip(tmpDescrip, theView);
});
theGroup.addElement(theLink);
} else {
var someLabel:Label = new Label();
someLabel.maxWidth = 580;
someLabel.text = textArray[i].toString();
theGroup.addElement(someLabel);
}
}
}
The issue that I was having is, I had multiple lables in a VGroup and needed them to wrap instead of extending past the containers set width. I was trying to integrate keywords into a dynamic paragraph of text. I could not use mx:Text because I needed each word to be its own component that allowed custom styling plus a mouse click even if the word was a keyword. Also the label max lines solution would not work because I am dealing with multiple lables in a VGroup and the VGroup needed to wrap its children not the label tags. I also could not use a TileGroup because it does not look right breaking a paragraph into a table looking component where each word is in its own column/row.
The solution I used was to count each character in the label being generated and add it to a variable to determine when I need to create a new HGroup that holds the labels and sits in a VGroup. I had to do this because I cannot determine the labels width until it renders because it is generated dynamically. This could not be done because as its render point is too late for me to move everything because the user can see all of this happening which is definitely not the desired effect.
Below is the code I used to solve this issue incase anyone else runs into this issue:
public static function setKeyWords(someText:String, theGroup:Group, theDictionary:Array, theView:Object):void {
theGroup.removeAllElements();
var textArray:Array = someText.split(' ');
var theCount:int = 0;
var theHGroup:HGroup = new HGroup();
var breakNum:int = 40;
theHGroup.percentWidth = 100;
for(var i:int = 0, l:int = textArray.length; i < l; i++) {
theCount += textArray[i].toString().length;
if(theCount >= breakNum) {
theGroup.addElement(theHGroup);
theHGroup = new HGroup();
theHGroup.percentWidth = 100;
theCount = 0;
}
if(checkForWord(theDictionary, textArray[i].toString())) {
theCount += 1;
var theLink:Label = new Label();
theLink.text = textArray[i].toString();
theLink.setStyle("color", "0xFFFF00");
theLink.setStyle("fontWeight", "bold");
theLink.maxWidth = 580;
//theLink.includeInLayout = false;
var tmpDescrip:String = theDescription;
theLink.addEventListener(MouseEvent.CLICK, function(evt:MouseEvent):void {
showToolTip(tmpDescrip, theView, 'keywords');
});
theHGroup.addElement(theLink);
} else {
theCount += 1;
var someLabel:Label = new Label();
someLabel.maxWidth = 580;
someLabel.text = textArray[i].toString();
//someLabel.includeInLayout = false;
theHGroup.addElement(someLabel);
}
}
if(theCount > 0)
theGroup.addElement(theHGroup);
}
This may not be the most effecient way to do this but it does work and takes little time to execute on the Iphone which is what I was aiming for.
Not fully sure I understand your question.
If you mean the Label's are truncated, you might want to set a percentWidth and wrap Labels with maxDisplayedLines:
someLabel.maxDisplayedLines = 10;
If you mean you want columns and rows to your Group layout, use TileGroup / TileLayout.
If the children of your group contain composite content that must float, some kind of includeInLayout=false might help.
If you want text to show in block of several lines, use mx:Text with width set.
To display something above HGroup, easiest way is to leave HGroup alone and just make transparent container (Canvas) above it. There you'll be free to display anything (just do the math to position it correctly.)