Skip to content

Instantly share code, notes, and snippets.

@gAmUssA
Created January 15, 2011 13:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gAmUssA/780910 to your computer and use it in GitHub Desktop.
Save gAmUssA/780910 to your computer and use it in GitHub Desktop.
The DataGridItemRenderer class defines the default item renderer for a DataGrid control.
package com.theriabook.controls.superGridClasses
{
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.utils.getQualifiedSuperclassName;
import flash.utils.getDefinitionByName;
import flash.utils.getQualifiedClassName;
import com.theriabook.controls.SuperGrid;
import mx.controls.listClasses.BaseListData;
import mx.controls.listClasses.IDropInListItemRenderer;
import mx.controls.listClasses.IListItemRenderer;
import mx.core.IDataRenderer;
import mx.core.IFlexDisplayObject;
import mx.core.IToolTip;
import mx.core.UIComponent;
import mx.core.UIComponentGlobals;
import mx.core.UITextField;
import mx.core.mx_internal;
import mx.events.FlexEvent;
import mx.events.ToolTipEvent;
import mx.managers.ILayoutManagerClient;
import mx.styles.CSSStyleDeclaration;
import mx.styles.IStyleClient;
import mx.styles.StyleManager;
import mx.styles.StyleProtoChain;
import mx.utils.ColorUtil;
import com.theriabook.printing.pdf.xdp.IXdpObject;
import com.theriabook.printing.geom.PNumber;
use namespace mx_internal;
/**
* Dispatched when the <code>data</code> property changes.
*
* <p>When you use a component as an item renderer,
* the <code>data</code> property contains the data to display.
* You can listen for this event and update the component
* when the <code>data</code> property changes.</p>
*
* @eventType mx.events.FlexEvent.DATA_CHANGE
*/
[Event(name="dataChange", type="mx.events.FlexEvent")]
/**
* The DataGridItemRenderer class defines the default item renderer for a DataGrid control.
* By default, the item renderer
* draws the text associated with each item in the grid.
*
* <p>You can override the default item renderer by creating a custom item renderer.</p>
*
* @see mx.controls.DataGrid
* @see mx.core.IDataRenderer
* @see mx.controls.listClasses.IDropInListItemRenderer
*/
public dynamic class DataGridItemRenderer extends UITextField implements IDataRenderer, IDropInListItemRenderer, ILayoutManagerClient, IListItemRenderer, IStyleClient, IXdpObject
{
include "../../core/Version.asinc";
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
/**
* Constructor.
*/
public function DataGridItemRenderer()
{
super();
tabEnabled=false;
ignorePadding=false;
addEventListener(ToolTipEvent.TOOL_TIP_SHOW, toolTipShowHandler);
inheritingStyles=nonInheritingStyles=StyleProtoChain.STYLE_UNINITIALIZED;
}
//--------------------------------------------------------------------------
//
// Variables
//--------------------------------------------------------------------------
/**
* @private
*/
private var invalidatePropertiesFlag:Boolean=false;
/**
* @private
*/
private var invalidateSizeFlag:Boolean=false;
//--------------------------------------------------------------------------
//
// Overridden properties: UIComponent
//
//--------------------------------------------------------------------------
//----------------------------------
// nestLevel
//----------------------------------
/**
* @private
*/
override public function set nestLevel(value:int):void
{
super.nestLevel=value;
UIComponentGlobals.layoutManager.invalidateProperties(this);
invalidatePropertiesFlag=true;
UIComponentGlobals.layoutManager.invalidateSize(this);
invalidateSizeFlag=true;
}
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
//----------------------------------
// data
//----------------------------------
/**
* @private
*/
private var _data:Object;
[Bindable("dataChange")]
/**
* The implementation of the <code>data</code> property as
* defined by the IDataRenderer interface.
*
* The value is ignored. Only the listData property is used.
* @see mx.core.IDataRenderer
*/
public function get data():Object
{
return _data;
}
/**
* @private
*/
public function set data(value:Object):void
{
_data=value;
dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
}
//----------------------------------
// listData
//----------------------------------
/**
* @private
*/
private var _listData:DataGridListData;
[Bindable("dataChange")]
/**
* The implementation of the <code>listData</code> property as
* defined by the IDropInListItemRenderer interface.
* The text of the renderer is set to the <code>label</code>
* property of the listData.
*
* @see mx.controls.listClasses.IDropInListItemRenderer
*/
public function get listData():BaseListData
{
return _listData;
}
/**
* @private
*/
public function set listData(value:BaseListData):void
{
_listData=DataGridListData(value);
UIComponentGlobals.layoutManager.invalidateProperties(this);
invalidatePropertiesFlag=true;
UIComponentGlobals.layoutManager.invalidateSize(this);
invalidateSizeFlag=true;
}
//----------------------------------
// styleDeclaration
//----------------------------------
/**
* @private
* Storage for the styleDeclaration property.
*/
private var _styleDeclaration:CSSStyleDeclaration;
/**
* Storage for the inline inheriting styles on this object.
* This CSSStyleDeclaration is created the first time that setStyle()
* is called on this component to set an inheriting style.
*/
public function get styleDeclaration():CSSStyleDeclaration
{
return _styleDeclaration;
}
/**
* @private
*/
public function set styleDeclaration(value:CSSStyleDeclaration):void
{
_styleDeclaration=value;
}
//--------------------------------------------------------------------------
//
// Overridden methods: UITextField
//
//--------------------------------------------------------------------------
/**
* @private
*/
override public function initialize():void
{
regenerateStyleCache(false)
}
/**
* @private
*/
override public function validateNow():void
{
if (data && parent)
{
var newColor:Number;
if (SuperGrid(_listData.owner).isItemHighlighted(_listData.uid))
{
newColor=getStyle("textRollOverColor");
}
else if (SuperGrid(_listData.owner).isItemSelected(_listData.uid))
{
newColor=getStyle("textSelectedColor");
}
else
{
newColor=getStyle("color");
}
if (newColor != explicitColor)
{
styleChangedFlag=true;
explicitColor=newColor;
invalidateDisplayList();
}
}
super.validateNow();
}
/**
* @copy mx.core.UIComponent#getStyle
*/
override public function getStyle(styleProp:String):*
{
return (styleManager.inheritingStyles[styleProp]) ? inheritingStyles[styleProp] : nonInheritingStyles[styleProp];
}
/**
* @copy mx.core.UIComponent#setStyle
*/
override public function setStyle(styleProp:String, newValue:*):void
{
if (styleProp == "styleName")
{
// Let the setter handle this one, see UIComponent.
styleName=newValue;
// Short circuit, because styleName isn't really a style.
return;
}
/*
if (styleProp == "themeColor")
{
// setThemeColor handles the side effects.
setThemeColor(newValue);
// Do not short circuit, because themeColor is a style.
// It just has side effects, too.
}
*/
// If this UIComponent didn't previously have any inline styles,
// then regenerate the UIComponent's proto chain (and the proto chains
// of this UIComponent's descendants).
var isInheritingStyle:Boolean=styleManager.isInheritingStyle(styleProp);
var isProtoChainInitialized:Boolean=inheritingStyles != StyleProtoChain.STYLE_UNINITIALIZED;
if (isInheritingStyle)
{
if (getStyle(styleProp) == newValue && isProtoChainInitialized)
return;
if (!styleDeclaration)
{
styleDeclaration=new CSSStyleDeclaration();
styleDeclaration.setStyle(styleProp, newValue);
// If inheritingStyles is undefined, then this object is being
// initialized and we haven't yet generated the proto chain. To
// avoid redundant work, don't bother to create the proto chain here.
if (isProtoChainInitialized)
regenerateStyleCache(true);
}
else
styleDeclaration.setStyle(styleProp, newValue);
}
else
{
if (getStyle(styleProp) == newValue && isProtoChainInitialized)
return;
if (!styleDeclaration)
{
styleDeclaration=new CSSStyleDeclaration();
styleDeclaration.setStyle(styleProp, newValue);
// If nonInheritingStyles is undefined, then this object is being
// initialized and we haven't yet generated the proto chain. To
// avoid redundant work, don't bother to create the proto chain here.
if (isProtoChainInitialized)
regenerateStyleCache(false);
}
else
{
styleDeclaration.setStyle(styleProp, newValue);
}
}
if (isProtoChainInitialized)
{
styleChanged(styleProp);
notifyStyleChangeInChildren(styleProp, isInheritingStyle);
}
}
//--------------------------------------------------------------------------
//
// Methods
//
//--------------------------------------------------------------------------
/**
* Documentation is not currently available.
* @review
*/
public function validateProperties():void
{
invalidatePropertiesFlag=false;
if (_listData)
{
var dg:SuperGrid=SuperGrid(_listData.owner);
var column:DataGridColumn;
try
{ //workaround for typecast of Adobe styling
column=this["styleName"];
if (column.owner.designMode)
{
border=true;
borderColor=0xcfcfcf;
}
}
catch (e:Error)
{
column=dg.columns[_listData.columnIndex];
}
text=_listData.label == "NaN" ? "" : _listData.label;
if (_data is DataGridColumn)
wordWrap=dg.columnHeaderWordWrap(column);
else
wordWrap=dg.columnWordWrap(column);
if (SuperGrid(_listData.owner).variableRowHeight)
multiline=true;
var dataTips:Boolean=dg.showDataTips;
if (column.showDataTips == false)
dataTips=false;
if (column.showDataTips == true || dg.designMode)
dataTips=true;
if (dataTips)
{
if (dg.designMode == true)
{
// nothing to do
}
else if (data is DataGridColumn && data.toolTip)
toolTip=data.toolTip;
else if (parent is Band)
toolTip=text;
else if (!(_data is DataGridColumn) && (textWidth > width || column.dataTipFunction || column.dataTipField || dg.dataTipFunction || dg.dataTipField))
{
toolTip=column.itemToDataTip(_data);
}
else
{
toolTip=null;
}
}
else
{
toolTip=null;
}
}
else
{
text=" ";
toolTip=null;
}
}
/**
* Documentation is not currently available.
* @review
*/
public function validateSize(recursive:Boolean=false):void
{
invalidateSizeFlag=false;
validateNow();
}
/**
* Documentation is not currently available.
* @review
*/
public function validateDisplayList():void
{
validateNow();
}
/**
* @copy mx.core.UIComponent#clearStyle
*/
public function clearStyle(styleProp:String):void
{
setStyle(styleProp, undefined);
}
/**
* @inheritDoc
* @review
*/
public function notifyStyleChangeInChildren(styleProp:String, recursive:Boolean):void
{
}
/**
* Sets up the <code>inheritingStyles</code>
* and <code>nonInheritingStyles</code> objects
* and their proto chains so that the <code>getStyle()</code> method can work.
*/
public function initProtoChain():void
{
styleChangedFlag=true;
var classSelector:CSSStyleDeclaration;
if (styleName)
{
if (styleName is CSSStyleDeclaration)
{
// Get the style sheet referenced by the styleName property
classSelector=CSSStyleDeclaration(styleName);
}
else if (styleName is IFlexDisplayObject)
{
// If the styleName property is a UIComponent, then there's a
// special search path for that case.
StyleProtoChain.initProtoChainForUIComponentStyleName(this);
return;
}
else if (styleName is String)
{
// Get the style sheet referenced by the styleName property
classSelector=styleManager.getStyleDeclaration("." + styleName);
}
}
// To build the proto chain, we start at the end and work forward.
// Referring to the list at the top of this function, we'll start by
// getting the tail of the proto chain, which is:
// - for non-inheriting styles, the global style sheet
// - for inheriting styles, my parent's style object
var nonInheritChain:Object=styleManager.stylesRoot;
/*
if (nonInheritChain.effects)
registerEffects(nonInheritChain.effects);
*/
var p:IStyleClient=parent as IStyleClient;
if (p)
{
var inheritChain:Object=p.inheritingStyles;
if (inheritChain == StyleProtoChain.STYLE_UNINITIALIZED)
inheritChain=nonInheritChain;
}
else
{
// Pop ups inheriting chain starts at Application instead of global.
// This allows popups to grab styles like themeColor that are
// set on Application.
// if (isPopUp)
// inheritChain = Application.application.inheritingStyles;
// else
inheritChain=styleManager.stylesRoot;
}
// Working backwards up the list, the next element in the
// search path is the type selector
var typeSelectors:Array=getClassStyleDeclarations();
var n:int=typeSelectors.length;
for (var i:int=0; i < n; i++)
{
var typeSelector:CSSStyleDeclaration=typeSelectors[i];
inheritChain=typeSelector.addStyleToProtoChain(inheritChain, this);
nonInheritChain=typeSelector.addStyleToProtoChain(nonInheritChain, this);
/*
if (typeSelector.effects)
registerEffects(typeSelector.effects);
*/
}
// Next is the class selector
if (classSelector)
{
inheritChain=classSelector.addStyleToProtoChain(inheritChain, this);
nonInheritChain=classSelector.addStyleToProtoChain(nonInheritChain, this);
/*
if (classSelector.effects)
registerEffects(classSelector.effects);
*/
}
// Finally, we'll add the in-line styles
// to the head of the proto chain.
inheritingStyles=styleDeclaration ? styleDeclaration.addStyleToProtoChain(inheritChain, this) : inheritChain;
nonInheritingStyles=styleDeclaration ? styleDeclaration.addStyleToProtoChain(nonInheritChain, this) : nonInheritChain;
}
/**
* @inheritDoc
* @review
*/
public function regenerateStyleCache(recursive:Boolean):void
{
initProtoChain();
}
/**
*
* @inheritDoc
*/
public function registerEffects(effects:Array /* of String */):void
{
}
/**
* @inheritDoc
* @review
*/
public function getClassStyleDeclarations():Array
{
var className:String=getQualifiedClassName(this)
className=className.replace("::", ".");
var decls:Array=[];
while (className != null && className != "mx.core.UIComponent" && className != "mx.core.UITextField")
{
var s:CSSStyleDeclaration=styleManager.getStyleDeclaration(className);
if (s)
{
decls.unshift(s);
}
try
{
className=getQualifiedSuperclassName(getDefinitionByName(className));
className=className.replace("::", ".");
}
catch (e:ReferenceError)
{
className=null;
}
}
return decls;
}
//--------------------------------------------------------------------------
//
// Event handlers
//
//--------------------------------------------------------------------------
/**
* The event handler to position the tooltip.
*
* @param event The event object.
*/
protected function toolTipShowHandler(event:ToolTipEvent):void
{
var toolTip:IToolTip=event.toolTip;
try
{
// Calculate global position of label.
var pt:Point=new Point(0, 0);
pt=localToGlobal(pt);
pt=root.globalToLocal(pt);
toolTip.move(pt.x, pt.y + height); //really!!!(height - toolTip.height) / 2);
var screen:Rectangle=systemManager.screen;
var screenRight:Number=screen.x + screen.width;
if (toolTip.x + toolTip.width > screenRight)
toolTip.move(screenRight - toolTip.width, toolTip.y);
}
catch (e:Error)
{
}
}
////////////////////////////////////////////////////////////////////////////
// IXdpObject
public function get xdpContent():Object
{
var o:XML=<field x={convert(x)} w={convert(width)} h={convert(height)} >
<ui ><textEdit hScrollPolicy="off" multiLine="1" vScrollPolicy="off"/></ui>
<para hAlign={getStyle("textAlign")} hScrollPolicy="off" multiLine="1" vScrollPolicy="off" minW="20mm" minH="10mm"/>
<value >
<text multiLine="1" >{text}</text></value>
<font typeface={getStyle("fontFamily")}
size={convert(getStyle("fontSize"))}
weight={getStyle("fontWeight")}
posture={getStyle("fontStyle")}
underline={getStyle("textDecoration") == "underline" ? 1 : 0}
>
<fill>
<color value={rgb(getStyle("color"))}/>
</fill>
</font>
<margin topInset="0.5mm" bottomInset="0.5mm" leftInset="0.5mm" rightInset="0.5mm"/>
<border>
<!--fill>
<color value={rgb(getStyle("backgroundColor"))}/>
</fill-->
<edge presence="hidden"/>
<edge presence={(parent["bandId"] == "H" || parent["bandId"] == "D") ? "visible" : "hidden"}/>
<edge presence="hidden"/>
<edge presence="hidden"/>
</border>
</field>;
/*
o = applyStdData(o);
typeface={getStyle("fontFamily")+"pt"}
for each(var cell:XdpBaseObject in cells)
{
o.appendChild(cell.xdpContent);
}
*/
//trace("xdpContentXML in DataGridItemRenderer: " + o);
return o;
}
private function convert(val:Number):String
{
return PNumber.px2pt(val) + "pt";
}
private function rgb(val:Number):String
{
return (val >> 16 & 255) + "," + (val >> 8 & 255) + "," + (val & 255);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment