A nice thing about using images in Flex you never have to worry about maintaining the proper aspect ratio. If you hard code a width or height would otherwise break that aspect ratio Flex inevitably ignores it and uses blank pixels to fill the extra space created around it. However, If you need a container to size based on a percentage AND constrain to say a 4:3 ratio it turns out there’s no way to make this happen (as an old mentor would say) “auto-magically”. Of course there’s an relatively easy way to achieve by binding an container to its own height or width property and adjusting the value as such:
Here an example where we want the height to take up the maximum space available and the width to adjust itself so that the resulting box maintains the 4:3 ratio.
<mx:Canvas height="100%" width="{(this.height * (4/3))}">
You could do the converse as well..but make sure you use division here since its the ratio is of width to height and we’re dealing with height first now.
<mx:Canvas height="{(this.width / (4/3))}" width="100%">
ian News
One of our animators recently handed me some Flash built training animations (SWF) that were to be viewed in our Flex shell. In this case we needed playback controls like pause, play, next, back and so on to work with these animations. The pause functionality in this case was problematic. Sometimes this just requires a simple stop() action but more often than not animators build animations that are comprised of many smaller MovieClip animations that are re-used quite a bit on the stage. Issuing a stop() on the root level MovieClip doesn’t stop all sub-timlines as they operate independently from the root timeline and doesn’t result in a true pause. You’ll need issue a stop on all children of the MovieClip in this case to freeze everything in its place.
You might have handled this same thing in AS2 using a for loop:
for (var m in this){
if (typeof(this[mov]=="movieclip"){
this[mov].stop();
}
}
All in all this worked nicely as it could grab the full hierarchy of children. Unfortunately this no longer works in AS3. The closest thing to it would be a for loop using the number of children in a DisplayObject.
for (var i:uint = 0; i < mc.numChildren; i++){
if (typeof(this[mov]=="movieclip"){
mc.getChildAt(i).stop();
}
}
The problem with this is it only gets the direct children of the DisplayObject and none of their children’s children – and so on. However, we can fix that by wrapping it in a recursive function.
private function stopAllMovieClips(mc:*) : void {
trace("Stop: ", mc.name);
if(mc is MovieClip) mc.stop();
for (var i:int = 0; i < mc.numChildren; i++)
if (mc.getChildAt(i) is MovieClip){
stopMovieClip(mc.getChildAt(i));
}
}
stopAllMovieClips(this);
Notice that you can’t strongly type the argument for this function because you’ll come across a different class types when sifting through all children (Sprite, MovieClip, Graphic, etc). Of course MovieClip isn’t the only type of object this will work on and you aren’t limited to stop(). Any descendant of DisplayObject that has children or Flex Container is fair game here and you can perform nearly any action you want.
ian Flex
Earlier today I needed a container with flat edges at the top and rounded edges at the bottom for something I was building. Unfortunately there isn’t a built in method to do this in Flex. Well, heres how. Create a new skin that extends the default HaloBorder skin and override its updateDisplayList.
package
{
import flash.display.*;
import flash.geom.*;
import flash.utils.*;
import mx.core.EdgeMetrics;
import mx.skins.halo.HaloBorder;
import mx.utils.ColorUtil;
import mx.utils.GraphicsUtil;
public class CustomCornerBorder extends HaloBorder
{
public function TopicMenuPopupBorder()
{
super();
}
override protected function updateDisplayList
(unscaledWidth:Number, unscaledHeight:Number):void{
var g:Graphics = graphics;
super.updateDisplayList(unscaledWidth, unscaledHeight);
var r:Number = getStyle("cornerRadius") as Number;
if (!r) r = 0;
var bg:uint = getStyle("backgroundColor") as uint;
if (!bg) bg = 0x000000;
drawRoundRect(0,0, unscaledWidth,unscaledHeight,
{ tl: 0, tr: 0, br: r, bl: r }, bg, 1);
}
}
}
If you take a peek in the Container class definition it uses a radius object to determine which sides are to be rounded. Unfortunately it doesn’t actually expose any of this to us developers. To add insult to injury there are no styles that correspond to the radius object so we have to hard code the desired radius values into our new border class like I’ve done above. If hard coding values isn’t your thing you could subclass your container and add a custom style in for this.
Lastly don’t forget to set the borderSkin property on your container for it all to work.
border-skin: ClassReference("com.proflightinc.view.skins.TopicMenuPopupBorder");
ian News
Ok, I’m not sure how I missed this and if its common knowledge then forget I said anything, but I found out today that you can do this:
height="{ (dropDown.height > descriptorBox.height)
? (dropDown.height + 50) : (descriptorBox.height + 50) }” />
Doesn’t look like much but its a quick and dirty way to have conditional bindings without having to use a binding class or getter/setter method to handle the logic. Call me lazy, but I think this is pretty cool.
ian AS3.0, Flex, News
This is something I’ve been putting together for a little while now. Thus far I’ve just been using it for my own personal and professional projects but I think its got some very desirable features and needs to be shared. Its a truly lightweight MVC framework that basically aims to keep things as short and simple as possible.
Here’s the long description:
apex-mvc is an lightweight framework for those don’t want to bother with a complex MVC framework and still find other “lightweight” frameworks unnecessarily cumbersome. It gives you the ability to access a central data model, central services, and central events.
What is unique about about Apex is that it provides a single point of access to all central entities through the static “Apex” class. This allows you to quickly reference your central entities from anywhere without having to continually request instances.
Here are some other features of apex-mvc:
apex makes configuring services by allowing them to defined in MXML while still providing central access.
apex is designed in a way that is mindful of intellisense making it easy to see all central data and services from anywhere in your application.
apex is easy to learn and easy to use so that you can focus on developing your application without getting caught up on your MVC framework.
Its being hosted over at google code. View the project page here
ian News