Archive for February, 2009

ActionScript 101: null vs. undefined

February 26, 2009

public const undefined:*

A special value that applies to untyped variables that have not been initialized or dynamic object properties that are not initialized. In ActionScript 3.0, only variables that are untyped can hold the value undefined, which is not true in ActionScript 1.0 and ActionScript 2.0. For example, both of the following variables are undefined because they are untyped and unitialized:

  • var foo;
  • var bar:*;

The undefined value also applies to uninitialized or undefined properties of dynamic objects. For example, if an object is an instance of the Object class, the value of any dynamically added property is undefined until a value is assigned to that property.

Results vary when undefined is used with various functions:

  • The value returned by String(undefined) is "undefined" (undefined is converted to a string).
  • The value returned by Number(undefined) is NaN.
  • The value returned by int(undefined) and uint(undefined) is 0.
  • The value returned by Object(undefined) is a new Object instance.
  • When the value undefined is assigned to a typed variable, the value is converted to the default value of the data type.

null Primary expression keywords

A special value that can be assigned to variables or returned by a function if no data was provided. You can use null to represent values that are missing or that do not have a defined data type.

The value null should not be confused with the special value undefined. When null and undefined are compared with the equality (==) operator, they compare as equal. However, when null and undefined are compared with the strict equality (===) operator, they compare as not equal.

Typed variables cannot be undefined (:Object for example, but not :*).

var stateProperty:String = getStyle(“stateProperty”);
trace(stateProperty==undefined);

In ActionScript3, the code above will get the following warning: “1012: Variables of type String cannot be undefined. The value undefined will be type coerced to String before comparison.”

Here if you have time to read.

Advertisements

Flex pattern: data renderer has to know about data

February 24, 2009

Halo framework provides a lot of out-of-shelf control classes that perform layout tasks, such as DataGrid and Tree. What they do is instantiating renderers based on their data provider and layout the renderers according to their own rules. In the Model/View architecture, these layout managers represent the view and the data provider object represents the model. Inside the trench, all the data renderers implement mx.core.IDataRenderer which requires them to have setter/getter for their data member.

The data setter method is the place where we hook up the renderer with its data; you normally also invalidate the component and/or fire events here when necessary. This also means unluckily we cannot stick in any kind of dataprovider and any kind of data renderers into the creator component and expect the latter to “automagically” hook up the data with the renderers. All the creator component do (and should be doing but not more) is to hook up data item with the individual renderer:

var renderer:UIComponent = _itemRendererFactory.newInstance();
IDataRenderer(renderer).data = _items[i];
renderers[i] = renderer;
addChild(renderer);

It’s individual renderer’s job to decide on how he wants to render the data and the hook is the data setter method. The following code shows how mx.controls.Button implements data interface.

private var _data:Object;

[Bindable(“dataChange”)]
[Inspectable(environment=”none”)]

/**
*  The <code>data</code> property lets you pass a value
*  to the component when you use it as an item renderer or item editor.
*  You typically use data binding to bind a field of the <code>data</code>
*  property to a property of this component.
*  ……
*/
public function get data():Object
{
return _data;
}

/**
*  @private
*/
public function set data(value:Object):void
{
_data = value;

//render the data we get
//dispatch the event
dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
}

So one data renderer would require certain format of dataprovider which may be different than that for another type of renderer. A real world analog is the manager only handles a piece of work to an individual and it’s up to that individual to decide how to process it, which is not the concern of the manager since the manager knows every little about the work itself; what the manager does is to choreograph the whole effort (setting-up, dividing, hooking up, coordinating, etc. of the data renderers) as a team. (Sort of 1 foot view vs. 5,000 feet view;) It’s kinda hard to get the same level of detail at different distances.)

The bottom line is, the renderer has to know about the data in order to render them. Yeah, common sense…

Class reference vs. class name

February 24, 2009

var ClassReference:Class = flash.utils.getDefinitionByName("flash.display.Sprite") as Class;

and

var className:String = flash.utils.getQualifiedClassName(thisObj);

It seems that flash.utils.getQualifiedClassName would only take a reference to an instantiated object (as opposed to a class). For example, the following code would return null:

flash.utils.getQualifiedClassName(String);

Which means there is no way of accessing a class name in a static member. For example, you cannot use these utility methods to get class name for your default CSS declaration since this requires we do this in a static method.

private static function classConstruct():Boolean
{
if(!StyleManager.getStyleDeclaration(CLASS_NAME))

……

Here and here.

flash drawing API 101

February 22, 2009

1. Always first call Shape.graphics.clear() before you really draw anything. Here.

2. If you want your drawings to show up, besides adding your Shape/Sprite, etc object to the display list, you would need to specify either the lineStyle (by calling graphics.lineStyle(thinckness:Number=null, color:unit=0. alpha:Number=null, etc);)or the fillColor (by calling graphics.beginFill(color:uint, alpha:Number=null))or both before you draw anything, _after_ you did #1. For lineStyle, you will at least specify the thinkness; for fill, the color, both are the first parameter of the associated drawing function calls:

//draw a stroke in rectangle, without fill
var _rect1:Shape = new Shape();
_rect1.graphics.clear();
_rect1.graphics.lineStyle(1);
_rect1.graphics.drawRect(300,50, 200, 200);
addChild(_rect1);

//draw a solid rectangle, without stroke
var _rect2:Shape = new Shape();
_rect2.graphics.clear();
_rect2.graphics.beginFill(0);
_rect2.graphics.drawRect(300,50, 200, 200);
_rect2.graphics.endFill();
addChild(_rect1);

Flex pattern: Set property name or type at run-time

February 19, 2009

Scenario: I felt confused/embarrassed when the Starbucks barista asked me “What kind of milk?” when I asked for a “Misto“. Me, standing rolling my eyes, with a few thoughts quickly spinning around/above my head: doesn’t all the milk look same here? Do they also put soy milk in the coffee? Or maybe they have black milk here? I couldn’t figure out what my options would be after 2 seconds. So I probed: “What kind of milk do you offer?:D” She kindly replied: “1%, 2%, skim, etc..”

I guess the barista was expecting some basic knowlege which I obviously didn’t acquire by culture. (Oh yeah she is from the coffee culture and me from the tea culture for a side note.)

Let’s go back to our pattern thread. As developers of components, we want to apply loose coupling philosophy to our component architecture. Sometimes classes need to obtain their values from other objects rather than through locally set values and type selectors.

  1. Sometimes we’d like to have the developer determine certain aspects of our components (with these aspects esp. being states or styles of our components). Flex pattern: If you are creating components that are creator and manager of the data renderers, and your component are altering the renderers states by expecting them to “have” certain states, instead of hard code those state names locally into your data renderers, expose sub component state values as styles of the creator object and let the developer set them at runtime.

    var stateProperty:String = getStyle("stateProperty");//currentState
    var rolloverState:String = getStyle("rolloverValue");
    ...
    renderers[i][stateProperty] = (i == selectedItemIndex)? selectedState:
    (i==hilightedItemIndex)? rolloverState:unselectedValue;

    One thing attempting to do when you write your own custom component is to dictate the states of your descendant components  in the ancestor component (e.g. the creator of item renderers intrudes into the framework of the itemRenderers).  As in the following code, the component developer requires (sort of, since it recovers by using NaN;)) that the renderer implement “selectedStates”. Doesn’t look very elegant.

    //Code in AnimatedRandomWalk.as
    override protected function commitProperties():void
    {
    //……
    /**it’s often the case that a component will have more information its item renderers might be interested in than just the data.  It’s the practice in Flex to define a separate interface to allow define the additional information your component might pass to an item renderer.  Try not to require that your item renderers implement this interface…it’s nice to provide customers with the option to invest less effort but still get a gracefully degrading experience.
    in this case, we think our item renderers might want to render differently based on whether they’re selected or not.  While in controlled situations, you could just explicitly set the ‘currentState’ property of your renderers, If you want to allow developers to swap in different item renderers, that’s not a great idea. It essentially hijacks the view states of the item renderer, and doesn’t allow the developer to add additional states or behavior.  Better to let them manage their own currentState.*/
    if (inst is IRandomWalkRenderer)
    IRandomWalkRenderer(inst).selectedState = (isNaN(selectedIndex)?  NaN:
    (selectedIndex == j)?     1:
    0);
    //……
    }

    With this being said, since our component _is_ interested in the states other than just data of the renderers, how do we let them know when we want them to change states? One thing we can do this more elegantly (or, hmm, “unobtrusively”) is to not to hard code the values of the states into our component since we don’t know what states the developers already have had in his plate and we don’t want to force the developers to implement those states as we require. But what we can do (tactfully;-)), is to expose our options (done by public members and styles in Flex) for these states and have the developers make their decisions of their own at run-time, just as the nice brista lady showed me what options I would have for the milk in my coffee. Of course the developer may completely ignore these options, which would require us to handle the situation gracefully, as mentioned as “degrading experience” by Ely in his RandomWalk component.

    Here is how Ely did it in his FishEye component :

    //snippets of code in FisheyeBase.as
    /**
    * update the state properties of all of the items, based on
    * the current hilighted and/or selected items
    */
    private function updateState():void
    {
    var stateProperty:String = getStyle(“stateProperty”);
    if(stateProperty != null)
    {
    var rolloverState:String = getStyle(“rolloverValue”);
    var selectedState:String = getStyle(“selectedValue”);
    var unselectedValue:String = getStyle(“unselectedValue”);
    if (unselectedValue == null || (isNaN(selectedItemIndex) && isNaN(hilightedItemIndex)))
    unselectedValue = getStyle(“defaultValue”);

    for(var i:int=0;i<renderers.length;i++)
    {
    renderers[i][stateProperty] = (i == selectedItemIndex)? selectedState:
    (i==hilightedItemIndex)? rolloverState:
    unselectedValue;
    }
    }
    }//endof snippets in FisheyeBase.as

    //in the “main” MXML, this is what is supposed for a developer to do:
    <qs:Fisheye xmlns:qs=”qs.controls.*” height=”100%” dataProvider=”{src}”
    hilightScaleSlope=”3″ hilightMinScale=”.2″
    stateProperty=”currentState” rolloverValue=”rollOver” defaultValue=”” selectedValue=”selected”
    horizontalAlign=”left”>
    <qs:itemRenderer>
    <Component>
    <qs:CachedLabel xmlns:f=”flash.filters.*” color=”#FFFFFF”>
    <qs:states>
    <State name=”selected”>
    <SetProperty name=”filters”>
    <value>
    <Array>
    <f:GlowFilter  color=”#888888″/>
    </Array>
    </value>
    </SetProperty>
    <SetStyle name=”color” value=”#E27C0E” />
    </State>
    <State name=”rollOver”>
    <SetProperty name=”filters”>
    <value>
    <Array>
    <f:GlowFilter  color=”#BBBBBB”/>
    </Array>
    </value>
    </SetProperty>
    </State>
    </qs:states>
    </qs:CachedLabel>
    </Component>
    </qs:itemRenderer>
    </qs:Fisheye>
    //endof main snippets

  2. In some other cases, we don’t know what type (of UIComponent) we would use to render certain data items, or in other words, we like the flexibility of being able to leave the decision up to the developer.

Concept: There is normally a two-tier hook to this kind of things. For case #1, first we store a reference to the _name_ of the property, and provide public ways for the developer to set the name of the property. Under the hood, we query the property name at run-time and wire it back to the parts, which have this property as their data member. After the we know the property of interest, we then retrieve and set all the real values. which actually set values for the aforementioned parts data member. For case #2, we store a reference to the _type_, often as an interface, in our class. When the time comes when we need to declare and initialize one of a concrete type, we take the type that the developer sets, or in the case it’s not defined, we can provide our abstract type.  Till now we can see #2 is usually associated with factory method pattern. It sounds strange and stretchy to me if we call #1 as “Factory property pattern” although it is an innovative attempt.

Solution:

For #1, they manifest in the form of styles of UIComponent.  The mx.styles.ISimpleStyleClient has a styleName getter which means “the source of this object’s style values”.  One of the scenarios is  the object that implements this interface inherits all the style values from the referenced UIComponen; Another use case is you can use a String which names a class selector that is defined in a CSS style sheet; A third case is to use CSSStyleDeclaration, such as StyleManager.getStyleDeclaration(“.headerStyle”)...

For #2, they appear in IFactory, ClassFactory which are used for creating item renderers.

//sample code for our customcomponent

private var _itemRenderer:IFactory;

public function CustomComponentConstruct()

{

...

_itemRenderer = new ClassFactory(Image);

...

}//end of sample code

/////////////////////////

//sample code for mx.core.ClassFactory

public var generator:Class

public function ClassFactory(generator:Class = null)
{
super();

this.generator = generator;
}
public function newInstance():*
{
//instantiate new class object. Note that we type "instance" as Object as opposed to Class:
var instance:Object = new generator();
//This is another pattern where we aggregate all children properties to their "owner"
if (properties != null)
{
for (var p:String in properties)
{
instance[p] = properties[p];
}
}

return instance;
}
//end of sample code for ClassFactory

Flex pattern: Aggregate sub-component styles into parent

February 7, 2009

Scenario: A lot of times, certain children components share certain properties among them (the values should be all the same for this group of children for this instance of parent component) and yet it would be inappropriate to set them as Static. For example, if you are creating a 3D carousel, the radius of the carousel, the angle between one carousel item to the one next to it, etc. should be the same (ok, the angle could be different for your carousel. So let’s assume it is for mine).

Pattern: Parent creating children . One pattern in Flex, when you create sub-components, you have your parent component does the creation job. In our 3D carousel example, you can have a Carousel component and a CarouselItem component. One of the jobs for Carousel is it becomes a factory of creating contained CarouselItem instances.

Pattern: Aggregating subcomponent styles into parent component. Another pattern in Flex is you can aggregate the styles of your child component into your parent component, even though your parent component does not actually “use” those styles. They are there since it’s convenient and they are automatically passed through to the contained subcomponent.

How: We do this by defining those styles in metadata in the parent component, which assigns itself as the styleName for the subcomponent instances, which makes these instances inherit all the style values defined on the parent component.

//these are the code inside Carousel class

[Style(name=”threeDRadius”), type=”Number”]

override protected function commitProperties():void

{

……

if(itemsDirty)
{
for(var i:int=0; i<_dataProvider.length; i++)
{
var c:CarouselItem = new CarouselItem();

c.styleName = this;
}
}

}

See “Tutorial: DisplayShelf component”

After Effects shortcut keys

February 6, 2009

Select layer >  “U”: All animated and scripted (w/ expressions) properties

Select layer> “S”:   Scale

Shift+ F3 > Graph keyframe

Numeric “0” (zero) > RAM preview

“=” > Zoom in timeline

“-” > Zoom out timeline

“.” (or Ctrl + “+”) >  Zoom in

“,” (or Ctrl + “-“) > Zoom out

“;” (semicolon) > Toggle on/off frame view

PageDown key > next frame

PageUp key > previous frame

Alt + “>” > nudge keyframe forward one frame

Shift drag > Snap keyframe to significant times

“k” > next keyframe

“j” > previous keyframe

Alt + click stopwatch in layer > Add/remove expressions

~ (Tilde) > Maximize panel

eclipse shortcut keys

February 3, 2009

Here and here.

ctrl + o -> show and jump to member (property/method) in current class

ctrl + space -> code hinting. Insert into the current position a member

ctrl + shift + o-> add missing import packages/classes into current class

Alt + LeftArrow/ RightArrow > Backward/Forward history

ctrl + L > go to line #

ctrl + M > Toggle between maximized/un-maximized mode of the current view

ctrl + F11 > Run the application

F11 > debug the application

Ctrl + Shift + F > Find text in files

Ctrl + Shift + T > Open a type (a class/interface)

Ctrl + Shift + R > Open a file (shortcut through Package Explorerer)

Ctrl + Shift + L > Show a list of shortcut keys

Ctrl + Shift + / > Add block comment (/**/)

Ctrl + Shift + \ > Remove block comment

Ctrl + Q > Go to the last caret location

6 steps in creating custom UIComponent in Flex (Halo framework)

February 2, 2009

Flex documentation.
The code here is just for demonstration purpose.

1. Initialization and configuration. You call Constructor() of the UIComponent. The constructor must have zero required parameters. This is due to the fact that there is no way to carry them into MXML tags. Inside constructor, you usually don’t do much here. A few things to do is to initialize all the states(properties) and hard code event listeners. Properties must expect that parts haven’t been created yet.

Public function UIComponent()
{
super();
focusRect = false;
tabEnabled = (this is IFocusManagerComponent);
tabChildren = false;
addEventListener(Event.ADDED, addedHandler);
addEventListener(Event.REMOVED, removedHandler);
}

2. Attachment of static parts. You can override createChildren () to attach static parts. “Static” parts are supporting visual assets such as masks and borders, which are needed for all dynamically generated parts throughout the lifetime of your component (regardless of the instances and states of your class).

Override protected function createChildren():void
{
_mask = new Shape();
_border = new Shape();
addChild(_mask);
addChild(_border);
if(_content!=null)
_content.mask = mask;
}

createChildren() is invoked by initialize(), which is the public method and is invoked when you add your component (explicitly calling addChild()/addChildAt() or adding MXML tags in your application) to the display list. Inside initialize(), 5 main lifecycle actions occur:
a.    preinitialize event is dispatched
b.    createChildren() is called
c.    initialize event is dispatched

First full invalidation/validation pass occurs (childrenCreated() is called, which then calls invalidateProperties(); invalidateSize(); invalidateDisplayList();  These will cause the validation methods to be invoked in order: commitProperties();measure();updateDisplayList())
d.    creationComplete event is dispatched
This basically completes the first full pass of invalidation/validation cycle.
AddChildren() also automatically invalidate its parent.

Hold on: From now on, since our UIComponent has entered the stage (in the display list), Flex is there to watch out any request for update from your component. LayoutManager (SystemManager?) governs any invalidation by calling the component’s callLater() method, which is listening to FlexEvent.RENDER event handler and FlexEvent.ENTER_FRAME event handler. The rule of game is if any of the following invalidation methods (shown on the left column) gets run at execution time, LayoutManager/SystemManager(?) will eventually invoke the corresponding method you defined for your component (shown on the right column).

InvalidateProperties()->commitProperties()
InvalidateSize()->measure()
invalidateDisplayList()->updateDisplayList()

3. Attachment of dynamic parts. Dynamic or data driven parts are created in commitProperties() method. Commit values typically set using a property setter. It is invoked by the framework before measurement and layout. This is the place to add/remove children not required through the life of the entire component (as opposed to createChildren()).

There is a definite pattern that should be followed in order to avoid extra work. See Dirty flags and storage variables.

A lot of times, Flex does dynamic parts by data renderers/ editors through factory pattern. Note that we don’t create parts in updateDisplayList(). This is because Adding children to a component automatically invalidates its size and display.  Since commit properties runs before measure() and updateDisplayList() runs, adding children in commitProperties() won’t accidentally trigger _another_ validation pass, which would happen if you tried to create them in updateDisplayList().

override protected function commitProperties():void
{
if(_itemsDirty)
{
_itemsDirty = false;
for(i = numChildren-1;i>=0;i–)
{
removeChildAt(numChildren-1);
}
_itemIndexMap = new Dictionary(true);
_children = [];

for(var i:int = 0;i<_dataProvider.length;i++)
{
var t:TiltingPane = new TiltingPane();
_itemIndexMap[t] = i;
t.addEventListener(MouseEvent.CLICK,itemClickHandler,false,0,true);
t.styleName = this;
_children[i] = t;

var content:UIComponent = UIComponent(_itemRenderer.newInstance());

IDataRenderer(content).data = _dataProvider.getItemAt(i);

t.content = content;
addChildAt(t,0);
}
}

4. Calculates the default (“natural” or “suggested” or “desired”) size, and optionally the default minimum size, of the component. The parent has ultimate say on sizing its child. You do this in measure(). measure() is implicitly invoked when component children change size. (Don’t call measure() on your children because the framework will do it for you). Measurement occurs from the bottom up. Framework optimizes away unnecessary calls to measure() so don’t rely on measure().(?)

override protected function measure():void
{
super.measure();
if(_currTarget!=null&&this.contains(_currTarget))
{
this.measuredMinHeight = this.measuredHeight = _currTarget.getExplicitOrMeasuredHeight();
this.measuredMinWidth = this.measuredWidth = _currTarget.getExplicitOrMeasuredWidth();
}
}

Note that you can use the convenient methods getExplicitOrMeasuredWidth()/getExplicitOrMeasuredHeight() on a UIComponent to get its explicit or measured dimensions. A tip is you can give a static number for measuredWidth/Height and then if your parts show up, then you go back and figure out the right sizes for them.

5. Draws and lays out (size and position) parts, using the allocated width and height. You do this in updateDisplayList().
You must set size and position for each child.

If the component has no children, this method is where you would do programmatic drawing using methods on the component’s Graphics object such as graphics.drawRect().

If the component has children, and if the child is not a UIComponent, set the x, y, width and height properties; if the child is a UIComponent, you would call the move() and setActualSize() methods on it since these methods aggregate invalidation events. Again, use setActualSize() and getExplicitOrMeasuredWidth(), etc. on each individual child to get their measured size or explicitly set size:

t.setActualSize(t.getExplicitOrMeasuredWidth(), t.getExplicitOrMeasuredHeight());

Components may do programmatic drawing even if they have children. In doing either, you should use the component’s unscaledWidth and unscaledHeight as its bounds.

It is important to use unscaledWidth and unscaledHeight instead of the width and height properties.

protected function get unscaledHeight():Number
{
return height / Math.abs(scaleY);
}

@param unscaledWidth Specifies the width of the component, in pixels, in the component’s coordinates, regardless of the value of the scaleX property of the component.

override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
if(_content)
{
var contentWidth:Number = _content.getExplicitOrMeasuredWidth();
var contentHeight:Number= _content.getExplicitOrMeasuredHeight();
var centerX:Number = unscaledWidth/2;
var p:Number = (Math.abs(_actualAngle)/90);
p = Math.sqrt(p);
_horizontalScale = 1 – p;
if(_actualAngle >= 0)
{
_verticalShear = p * -kPerspective;
}
else
{
_verticalShear = p * kPerspective;
}
_verticalShearEffect = contentWidth/2 * _verticalShear;
_content.setActualSize(contentWidth,contentHeight);                perspectiveDistort(centerX,0,contentWidth,contentHeight);
var borderColor:Number = getStyle(“borderColor”);
var borderThickness:Number = getStyle(“borderThickness”);
var g:Graphics = _border.graphics;
g.clear();
if(!isNaN(borderColor) && !isNaN(borderThickness))
{
g.lineStyle(borderThickness,borderColor,1,false,LineScaleMode.NORMAL,CapsStyle.NONE,JointStyle.MITER);
drawPerspectiveFrame(g,centerX,0, contentWidth, contentHeight);
}
if(_reflectionBitmap == null)
{
createReflectionBitmap(_content);
}                positionReflectionBitmap(centerX,0,contentWidth,contentHeight);
}
}

6. Detachment from display list. Todo. Remove listeners, clean up references, etc.