Menu:

Sponsor

Discover Master of Alchemy, our first iPad/iPhone and iPod touch game!

Follow Me

 

Forum's topics

Latest Files

Archives

Top Rated

Categories

Photo Gallery


Flash CellRenderer howto

3.1 The Image Field and NumericStepper field

For the others custom fields we need to proceed in a similar way (create an empty movieclip and associate to it a class file).
For the second custom field
column.cellRenderer = "imageCellRender" // [image] cell renderer

the one containing image do the follow steps:
- create a new Symbol in library: imageCellRender, with linkage name of imageCellRender and associated AS2 class: imageCellRender
- in this symbol just create a new empty movieclip (i will use this to load the image into): "img"

the AS2 class associated with is:


import mx.core.UIComponent;

class imageCellRender extends UIComponent {
    var img:MovieClip;
    var url:String;
    var listOwner:MovieClip;
    // the reference we receive to the list
    var getCellIndex:Function;
    // the function we receive from the list
    var getDataLabel:Function;
    // the function we receive from the list
    function imageCellRender() {
    }
    function createChildren(Void):Void {
        size();
    }
    function setValue(str:String, item:Object, sel:Boolean):Void {
        img._visible = (item[getDataLabel()] != undefined);
        //We move the head to the label matching 
        //current cell value
        if(item[getDataLabel()] != this.url){
            img.loadMovie(item[getDataLabel()]);
            this.onEnterFrame = function(){
                if(img.getBytesLoaded() >= img.getBytesTotal() && img.getBytesTotal() > 4 && img._width > 4){
                    this.url = item[getDataLabel()]
                    delete this.onEnterFrame;
                }
            }
        }
    }
    function size(Void) : Void
    {
        img._y = (img._height/2) - 2
    }    
}

the function automatically invoked from the datagrid is setValue and here we need simply to load the image into the "img" movieclip (item[getDataLabel()] is the string we receive from DataGrid)

 

- For the numeric stepper field things are different for a little.
This is the command for associate the stepper custom field to the DataGrid column:
column.cellRenderer = "numericRenderer" // cell renderer

- As previous create a new movieclip numericRenderer, linkage: numericRenderer, and AS2 class: NumericRenderer
-
Enter in the movieclip just created and drag into the NumericStepper component (name it "stepper")
- in the same frame create a new layer with this code:

stepper.addEventListener("change", this._parent);
stepper.value = this.value
this.watch("value", this.setNewValue)

function setNewValue(id, old_v, new_v){
stepper.value = new_v
}

We just assign a new watcher which everytime the value associate to the field changes, will change the value of the steppers itself.
The Class associated do this:


import mx.core.UIComponent

import mx.controls.NumericStepper

class NumericRenderer extends UIComponent
{
    var stepper_cont : MovieClip;
    var stepper : MovieClip;
    var listOwner : MovieClip; // the reference we receive to the list
    var getCellIndex : Function; // the function we receive from the list
    var    getDataLabel : Function; // the function we receive from the list

    function NumericRenderer()
    {
    }

    function createChildren(Void) : Void
    {
        stepper = stepper_cont.stepper
        size();
    }

    // note that setSize is implemented by UIComponent and calls size(), after setting
    // __width and __height
    function size(Void) : Void
    {
        stepper.setSize(80, __height);
        stepper._x = (__width-80)/2;
        stepper._y = (__height-22)/2;
    }

    function setValue(str:String, item:Object, sel:Boolean) : Void
    {
        if(item[getDataLabel()] == undefined){
            stepper_cont._visible = false
        } else {
            stepper_cont._visible = true
        }
        stepper_cont.value = item[getDataLabel()];
    }

    function getPreferredHeight(Void) : Number
    {
        return 22;
    }

    function getPreferredWidth(Void) : Number
    {
        return 80;
    }

    function change()
    {
        listOwner.dataProvider.editField(getCellIndex().itemIndex, getDataLabel(), stepper_cont.stepper.value);
        listOwner.selectedIndex = getCellIndex().itemIndex
        listOwner.dispatchEvent({ type:"cellEdit"});
    }

}


Here We have:
- createChildren which is automatically invoked and here just assign the variable stepper to the component we dragged into our movieclip
-

setValue which if the value is undefined just make invisible the movieclip itself, otherwise set the value associate to the field (this value will be used by the watch function we previously declared)
- change which is used by the component stepper once its value change and this propagate the "cellEdit" method of the DataGrid component (this means that you will receive an event "cellEdit" if you add an eventlistener to the datagrid component)

All the API of the cellRenderer can be found here:
http://livedocs.macromedia.com/...file=16_cell4.htm

4. Component Listener

Last step to do is to listen for events of our component (like cellEdit or cellPress).
Click on the DataGrid component you have on the stage and assign this code


on (cellEdit) {

    var sel = this.selectedIndex
    var data = this.getItemAt(sel)
    var price:Number = data.price
    var quantity:Number = data.quantity
    data.total = price*quantity
    data.available = data.quantity > 0
}
on (cellPress) {
    var sel = this.selectedIndex
    var data = this.getItemAt(sel)    
    if(data.available  == false and data.quantity > 0){
        data.quantity = 0
    } else if(data.available == true and data.quantity == 0){
        data.quantity = 1
    }
    var price:Number = data.price
    var quantity:Number = data.quantity
    data.total = price*quantity    
}

CellEdit will be invoked when the NumericStepper changed and i use this to change the "total" property of the component each time the stepper change.
CellPress, instead, start every time you click on the "checkbox" component in the datagrid

Note that this is the same as using the "addEventListener" command, but doing this from the movie actions directly

 

5. Conclusion

I think i explained you in a clear way how the DataGrid, and others macromedia component can be easily be customized without changing their library elements (like for example we used to do woth flash mx).
there are many potenetial way to customize a "cellRender", i just wanted to show you some..
Other great examples of cellRenderer can be found here:
http://philflash.inway.fr/example.html


In the same way I hope you see how easy is to use the Serializer class in order to receive complex data type from PHP. In fact we don't need to parse the data or an XML for populating the datagrid with the variables come from PHP.

 

Download the tutorial files from here