Reputation: 1044
I have a component in Flex, and part of that component is a label. Is there a way to automatically adjust the font size to fit into its container?
Upvotes: 1
Views: 2379
Reputation: 1395
If you mean a single-line label then this is the component that may help you. Consider that it can only make it's font size smaller (as a reaction to container's width reduction).
import flash.events.Event;
import flash.text.TextLineMetrics;
import mx.controls.Label;
import mx.events.FlexEvent;
public class ElasticLabel extends Label {
private static const EXTRA_SPACE:Number = 2;
private static const MIN_FONT_SIZE:Number = 6;
private var fontResizeRequired:Boolean = false;
public function ElasticLabel() {
super();
addEventListener("explicitMaxWidthChanged", triggerFontResize);
addEventListener(FlexEvent.VALUE_COMMIT, triggerFontResize);
}
private function triggerFontResize(event:Event):void {
fontResizeRequired = true;
}
private function get currentWidth():Number {
var textMetrics:TextLineMetrics = measureText(text);
var textWidth:Number = textMetrics.width;
var paddings:Number = 0;
var paddingLeft:Number = getStyle("paddingLeft");
if (!isNaN(paddingLeft)) paddings += paddingLeft;
var paddingRight:Number = getStyle("paddingRight");
if (!isNaN(paddingRight)) paddings += paddingRight;
return textWidth + paddings + EXTRA_SPACE;
}
private function resizeFont():void {
if (!isNaN(maxWidth) && maxWidth > 0) {
var fontSize:Number = getStyle("fontSize") as Number;
while (maxWidth < currentWidth
&& fontSize > MIN_FONT_SIZE) {
fontSize -= 0.5;
setStyle("fontSize", fontSize);
}
}
}
override protected function updateDisplayList(unscaledWidth:Number,
unscaledHeight:Number):void {
super.updateDisplayList(unscaledWidth, unscaledHeight);
if (fontResizeRequired) {
resizeFont();
fontResizeRequired = false;
}
}
}
Upvotes: 0
Reputation: 10409
Not automatically (at least not that I know of), without setting up some sort of event handler, and taking action on the occurrence of some event. Here's a simple AIR app that demonstrates one approach -- in this case, a resize event triggering a change in the fontSize of a Label:
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="this_creationComplete()">
<mx:Script>
<![CDATA[
import mx.binding.utils.BindingUtils;
import mx.binding.utils.ChangeWatcher;
[Bindable]
public var myValue:int = 0;
private function this_creationComplete():void
{
setSize();
addEventListener(Event.RESIZE, handleResize);
}
private function handleResize(event:Event):void
{
setSize();
}
private function setSize():void
{
lbl.setStyle("fontSize", this.height / 2);
}
]]>
</mx:Script>
<mx:Label id="lbl" text="Hello, world!" />
</mx:WindowedApplication>
Here, when the app gets resized, the label's fontStyle property gets changed to one-half the app's height; scale it up and down and you'll see how it works. There are certainly other approaches, as always, but because we're dealing with styles and not bindable properties, a little custom coding is most likely called for. Hope it helps!
Upvotes: 1