Wednesday, February 22, 2012

Spark Skinnable GridItemRenderer

I am currently working on a project with a requirement to have skinnable grids with changeable skins. Now working with itemrenderers in Spark, I've found it to be painfully similar to the Halo days. I was thinking to myself it would have been nice if GridItemRenderer extended SkinnableComponent instead of a Group but whatever, I'm sure there is a good explanation. Anyhow, I took it upon myself to create a quick SkinnableGridItemRenderer to fill my void.

I'm not too sure if this scales and i'm not too sure if tooltips will work perfectly but it's a good start and i don't have those requirements so it works great for what I need it for. By the way, I didn't include all the states so you'll have to add the others if you need them.

package com.datagrid
{ 
 import flash.events.Event;
 import flash.events.TextEvent;
 
 import mx.events.FlexEvent;
 
 import spark.components.Grid;
 import spark.components.gridClasses.GridColumn;
 import spark.components.gridClasses.IGridItemRenderer;
 import spark.components.supportClasses.SkinnableComponent;
 import spark.components.supportClasses.TextBase;

 [Event(name="dataChange", type="mx.events.FlexEvent")]

 //--------------------------------------
 //  Excluded APIs
 //--------------------------------------

 [Exclude(name="transitions", kind="property")]

 [SkinState("disabled")]
 [SkinState("selected")]
 [SkinState("hovered")]
 [SkinState("normal")]
 [SkinState("down")]

 public class SkinnableGridItemRenderer extends SkinnableComponent implements IGridItemRenderer
 {
  [SkinPart(required="false")]
  public var labelDisplay:TextBase;

  //----------------------------------
  //  column
  //----------------------------------

  private var _column:GridColumn=null;

  [Bindable("columnChanged")]

  /**
   *  @inheritDoc
   *
   *  

The Grid's updateDisplayList() method sets this property * before calling preprare()

. * * @default null * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 2.5 * @productversion Flex 4.5 */ public function get column():GridColumn { return _column; } /** * @private */ public function set column(value:GridColumn):void { if (_column == value) return; _column=value; dispatchChangeEvent("columnChanged"); } //---------------------------------- // rowIndex //---------------------------------- private var _rowIndex:int=-1; [Bindable("rowIndexChanged")] public function get rowIndex():int { return _rowIndex; } /** * @private */ public function set rowIndex(value:int):void { if (_rowIndex == value) return; _rowIndex=value; dispatchChangeEvent("rowIndexChanged"); } //---------------------------------- // dragging //---------------------------------- private var _dragging:Boolean; public function get dragging():Boolean { return _dragging; } public function set dragging(value:Boolean):void { if (_dragging == value) return; _dragging=value; } //---------------------------------- // label //---------------------------------- private var _label:String; public function get label():String { return _label; } public function set label(value:String):void { if (_label == value) return; _label=value; if (labelDisplay) labelDisplay.text=label; } //---------------------------------- // columnIndex //---------------------------------- public function get columnIndex():int { return (column) ? column.columnIndex : -1; } //---------------------------------- // selected //---------------------------------- private var _selected:Boolean; public function get selected():Boolean { return _selected; } public function set selected(value:Boolean):void { if (_selected == value) return; _selected=value; invalidateDisplayList(); invalidateSkinState(); } //---------------------------------- // showsCaret //---------------------------------- private var _showsCaret:Boolean; public function get showsCaret():Boolean { return _showsCaret; } public function set showsCaret(value:Boolean):void { if (_showsCaret == value) return; _showsCaret=value; } //---------------------------------- // down //---------------------------------- /** * @private * storage for the down property */ private var _down:Boolean=false; /** * @inheritDoc * * @default false * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 2.5 * @productversion Flex 4.5 */ public function get down():Boolean { return _down; } /** * @private */ public function set down(value:Boolean):void { if (value == _down) return; _down=value; invalidateDisplayList(); invalidateSkinState(); } //---------------------------------- // grid //---------------------------------- /** * Returns the Grid associated with this item renderer. * This is the same value as column.grid. * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 2.5 * @productversion Flex 4.5 */ public function get grid():Grid { return (column) ? column.grid : null; } //---------------------------------- // hovered //---------------------------------- private var _hovered:Boolean=false; /** * @inheritDoc * * @default false * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 2.5 * @productversion Flex 4.5 */ public function get hovered():Boolean { return _hovered; } /** * @private */ public function set hovered(value:Boolean):void { if (value == _hovered) return; _hovered=value; invalidateDisplayList(); invalidateSkinState(); } //---------------------------------- // data //---------------------------------- private var _data:Object; public function get data():Object { return _data; } public function set data(value:Object):void { if (_data == value) return; _data=value; } override protected function getCurrentSkinState():String { var retState:String="normal"; if (!enabled) { retState="disabled"; } else if (_down) { retState="down"; } else if (_hovered) { retState="hovered"; } else if (_selected) { retState="selected"; } return retState; } //---------------------------------- // skin parts //---------------------------------- override protected function partAdded(partName:String, instance:Object):void { super.partAdded(partName, instance); if (instance == labelDisplay) { labelDisplay.text=label; } } private function dispatchChangeEvent(type:String):void { if (hasEventListener(type)) dispatchEvent(new Event(type)); } public function prepare(hasBeenRecycled:Boolean):void { } public function discard(willBeRecycled:Boolean):void { } } }

Here's an example skin:


 
 
  [HostComponent("com.datagrid.SkinnableGridItemRenderer")]
 

 
  
  
  
  
  
 

 


Where to go from here? Well you can easily override this base class and add additional functionality and skin states to accomplish pretty much anything. All this isn't really necessary depending on your project setup but we use themes and it was easier with this approach and the styling was much easier.

No comments:

Post a Comment