Multi line text in Flex doesnt recalculate when runtime css is changed - apache-flex

For loading time considerations I am using a runtime css file in my Flex Application.
I am having a problem with a multi line text control :
<mx:Text id="txtDescription" selectable="false"
styleName="imageRolloverButtonTextDark" width="100%" textAlign="center"
text="{_rolloverText}"/>
When my CSS stylesheet has loaded the text style correctly changes, but the height is not recalculated. It appears to be just a single line field.
FYI: The control is not actually visible, and triggered by a rollover. So I dont really care if the stylesheet hasnt loaded and they get standard system text. I jsut want it to be the correct height when it has been loaded.

Per the Adobe documentation for Text
Sizing a Text control
Flex sizes the
Text control as follows:
If you specify a pixel value for both
the height and width properties, any
text that exceeds the size of the
control is clipped at the border.
If you specify an explicit pixel
width, but no height, Flex wraps the
text to fit the width and calculates
the height to fit the required number
of lines.
If you specify a percentage-based
width and no height, Flex does not
wrap the text, and the height equals
the number of lines as determined by
the number of Return characters.
If you specify only a height and no
width, the height value does not
affect the width calculation, and Flex
sizes the control to fit the width of
the maximum line.
As a general rule, if you have long
text, you should specify a pixel-based
width property. If the text might
change and you want to ensure that the
Text control always takes up the same
space in your application, set
explicit height and width properties
that fit the largest expected text.
So the trick I've used to deal with this is to have the Text get its width via a binding expression from whatever container limits it's width, typically the immediate parent.
e.g.
<mx:Canvas id="box" width="100%" backgroundColor="Red">
<mx:Text width="{box.width}" text="{someReallyLongString}" />
</mx:Canvas>

For any one else who has this problem, The solution I found was to create a custom component extending the mx.controls.Text
and then override the styleChange() Method, and explicitly call the invalidateDisplayList() method for the text field once the style has been applied.
It should be called automatically when the styleis changed but no...for some reason in flex 3.5 it is not.
public class TextObject extends Text { //...
override public function styleChanged(styleProp:String):void { invalidateDisplayList(); }
}
Hope that save some one all the time I lost on it.

Could you use a fixed pixel width instead of 100%? I've had issues with 100% being wrongly calculated on dynamic text controls before.

Related

How do I truncate a Flex StyleableTextField after two lines?

In my Flex 4.5 mobile app, I have an actionScript item renderer (that derives from Flex's LabelItemRenderer). I want to fit in exactly 2 lines of text, and then truncate the rest. The width and height of the label are fixed and known statically.
How can I do this? The StyleableTextField.truncateToFit() method only works for one line of text.
I've set wordWrap = true, so the text now flows into the second line - but I need to truncate the text if it doesn't fit in two lines.
I need it to show all the text if there is only one line. (in both cases the label should be vertically middle-aligned in my renderer)
I know how to override layoutContents to do sizing and positioning etc of the StyleableTextField. So I'm looking specifically for ideas to implement custom text truncation with the StyleableTextField).
Any ideas?
Unless you're using something specific to the StyleableTextField try the s:Label. It has a property maxDisplayedLines which you could set to 2 and it will handle the truncation.

Flex: Determining number of lines a spark text area can hold without overflowing

I want to implement paging in a spark text area. For that I want to find out the number of lines a spark textArea can hold before the scrollbars appear and just feed that much lines to the text area.
http://blog.flexexamples.com/2010/01/13/determining-the-number-of-lines-in-a-spark-richeditabletext-control-in-flex-4/
The number of lines a TextArea can hold before a vertical ScrollBar appear is determinated by the heightInLines property.
The code
var number_of_lines:int=textArea.heightInLines;
will return inside the variable number_of_lines the number of lines you are looking for, and textArea is the id of the TextArea object you are checking.
var numLines:int=t.heightInLines;
var numChars:int=t.widthInChars;
The documentation:
spark.components.TextArea.heightInLines():Number The default height of
the control, measured in lines. The control's formatting styles, such
as fontSize and lineHeight, are used to calculate the line height in
pixels.
You would, for example, set this property to 5 if you want the height
of the RichEditableText to be sufficient to display five lines of
text.
If this property is NaN (the default), then the component's default
height will be determined from the text to be displayed.
This property will be ignored if you specify an explicit height, a
percent height, or both top and bottom constraints.
RichEditableText's measure() method uses widthInChars and
heightInLines to determine the measuredWidth and measuredHeight. These
are similar to the cols and rows of an HTML TextArea.
Since both widthInChars and heightInLines default to NaN,
RichTextEditable "autosizes" by default: it starts out very small if
it has no text, grows in width as you type, and grows in height when
you press Enter to start a new line.

Flex: Why does setting scaleX/Y in mxml effect the components size but setting it in actionscript does not?

I'm playing around with the scaleX/Y in the canvas tag and have noticed some strange behaviour. When I set scale in in mxml the width and height of the canvas are adjusted accordingly. For example if I have a canvas like this:
<mx:Canvas width="1000" height="1000" scaleX="0.1" scaleY="0.1" />
The canvas now appears on screen to have a width and height of 100 and if inside my creationComplete callback I check the width and height property they are indeed 100.
But if I do exactly the same thing except I set the scaleX/Y property from actionscript the canvas on screen appears to have a width and height of 100 as expected, but when I check the width and height property of the canvas they are still at the previous values of 1000.
Could anyone help me understand what is going on and also tell me if there is any method that will refresh the width and height values so that they are correct?
Thanks,
Chris
At what point in the Canvas' lifecycle are you adjusting the scaleX/Y properties in Actionscript? And then, at what point are you re-checking them?
It may be helpful to examine this white paper on Flex component lifecycles (PDF) to pick the right timing for actionscript-based visual component tweaking.

Flex custom button component

I want my custom button to look like the button sample below.
More specifically, I want the width of the button to be determined by the width of the largest word in the label (i.e. width of "Elongated" in my example). The label must wrap, not truncate.
And I want only one pixel between the top edge of the icon and my button's top edge.
I have tried lots of things but to no avail so far. I have reduced the horizontalGap and verticalGap to zero and padding to zero. But still nothing. Please help.
Here's what I have right now:
<mx:Button top="0" cornerRadius="2" paddingLeft="0" paddingRight="0" leading="0" letterSpacing="0" paddingTop="0" paddingBottom="0" verticalGap="0" horizontalGap="0" textAlign="center" labelPlacement="bottom" icon="{MyIcon}" height="60" width="75" label="Elongated Label" fontSize="10" />
That's not at all simple.
You will need to create your own button,
public class Mybutton extends Button {...}
override createChildren and set the word wrap of the IUITextField used for the label to true.
override measure and use your own line metrics to determine the width that the button should be. If you get the measure right, the button will lay itself out properly.
I don't have a dev environment in front of me at the moment, but something along these lines should work:
Set truncateToFit property of the Label to false (OR use a TextField with wordWrap set to true - I think this should keep the words together as much as possible).
I haven't had the need to use any of the above yet, and hopefully you haven't tried them yet because it would be an easy solution to a part of your problem. Without any code, I'm not sure why padding didn't work, but maybe it's something to do with the word truncation.
As an alternative, why not use a Button, embed or specify a source for your icon and decide where to place the text by specifying the object's labelPlacement property?
EDIT: Since there's no property in Button about wordWrap, as they would recommend in the Adobe Flex forums for such questions regarding sizing based on content where there is no automatic feature to do that, you have to find the longest word and adjust the width of the button (i.e.: in the creationComplete event). Experimenting to find the font to pixel ratio would be my best bet (or you can use a Monospace font where all the characters are given the same space thereby simplifying the estimation):
creationComplete="event.target.width=returnMyWidth();"
As for the padding, it may be related to the custom width that you had set or it may be from embedding the image automatically setting a padding by being included - I'm not really sure, so it would be good if someone can offer a comment based on experience with this.

In Flex, how can I get the dimensions of a childless canvas component at runtime?

One of my components looks like this:
<mx:Canvas id="grid" width="100%" height="100%"></mx:Canvas>
On creationComplete, I load some spirte that I want to scale and position based on the dimensions of the canvas to create a custom grid layout, but when I access the dimensions of 'grid' I get 0 and 0. Is there any way to get the dimensions without assigning absolute values?
I can't check this at the moment but can you access the measuredHeight and measuredWidth?
My understanding is that unless the Canvas contains one or more DisplayObject children, it will always report its width and height properties as 0, regardless of the percentage sizings you may have applied to it.
You could always add an empty dummy DisplayObject to the Canvas, but that wouldn't be very elegant. Depending on how you've planned to implement your custom grid, it's possible you'll have to rethink the design...
Is it possibly created but not yet displayed (e.g. visible)? Since final size and shape is derived, it doesn't happen until the thing actually needs to be drawn. Width and height are documented to be the values actually in use - there are even events for when they change.
Worst case, try trapping it out in the canvas Resize event.
have you tried binding the width and height of the Canvas to its parent? If it is 100%, than it will have the same size as its parent and you could either bind or size your Sprite (UIComponent) based on the parent container of the Canvas.

Resources