//////////////////////////////////////////////////////////////////////////////// // // Licensed to the Apache Software Foundation (ASF) under one or more // contributor license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright ownership. // The ASF licenses this file to You under the Apache License, Version 2.0 // (the "License"); you may not use this file except in compliance with // the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // //////////////////////////////////////////////////////////////////////////////// package mx.controls.dataGridClasses { import flash.display.DisplayObject; import flash.geom.Point; import flash.geom.Rectangle; import flash.utils.getDefinitionByName; import flash.utils.getQualifiedClassName; import flash.utils.getQualifiedSuperclassName; import mx.controls.DataGrid; 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.UIFTETextField; import mx.core.mx_internal; import mx.events.FlexEvent; import mx.events.InterManagerRequest; import mx.events.ToolTipEvent; import mx.managers.ILayoutManagerClient; import mx.managers.ISystemManager; import mx.styles.CSSStyleDeclaration; import mx.styles.IStyleClient; import mx.styles.StyleManager; import mx.styles.StyleProtoChain; import mx.utils.PopUpUtil; use namespace mx_internal; /** * Dispatched when the data property changes. * *

When you use a component as an item renderer, * the data property contains the data to display. * You can listen for this event and update the component * when the data property changes.

* * @eventType mx.events.FlexEvent.DATA_CHANGE * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Event(name="dataChange", type="mx.events.FlexEvent")] /** * The FTEDataGridItemRenderer class defines the default item renderer for a * DataGrid control used with FTEText. By default, the item renderer * draws the text associated with each item in the grid. * *

You can override the default item renderer by creating a custom item renderer.

* * @see mx.controls.DataGrid * @see mx.core.IDataRenderer * @see mx.controls.listClasses.IDropInListItemRenderer * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public class FTEDataGridItemRenderer extends UIFTETextField implements IDataRenderer, IDropInListItemRenderer, ILayoutManagerClient, IListItemRenderer, IStyleClient { include "../../../spark/core/Version.as"; //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- /** * Constructor. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function FTEDataGridItemRenderer() { super(); tabEnabled = false; mouseWheelEnabled = 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 data property as * defined by the IDataRenderer interface. * *

The value is ignored. Only the listData property is used.

* * @see mx.core.IDataRenderer * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ 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 listData property as * defined by the IDropInListItemRenderer interface. * The text of the renderer is set to the label * property of the listData. * * @see mx.controls.listClasses.IDropInListItemRenderer * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get listData():BaseListData { return _listData; } /** * @private */ public function set listData(value:BaseListData):void { _listData = DataGridListData(value); if (nestLevel && !invalidatePropertiesFlag) { 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 object is created the first time that * the setStyle() method * is called on this component to set an inheriting style. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ 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 (DataGridBase(_listData.owner).isItemHighlighted(_listData.uid)) { newColor = getStyle("textRollOverColor"); } else if (DataGridBase(_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() * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ override public function getStyle(styleProp:String):* { return (styleManager.inheritingStyles[styleProp]) ? inheritingStyles[styleProp] : nonInheritingStyles[styleProp]; } /** * @copy mx.core.UIComponent#setStyle() * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ 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(null, styleManager); styleDeclaration.setLocalStyle(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.setLocalStyle(styleProp, newValue); } } else { if (getStyle(styleProp) == newValue && isProtoChainInitialized) return; if (!styleDeclaration) { styleDeclaration = new CSSStyleDeclaration(); styleDeclaration.setLocalStyle(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.setLocalStyle(styleProp, newValue); } } if (isProtoChainInitialized) { styleChanged(styleProp); notifyStyleChangeInChildren(styleProp, isInheritingStyle); } } //-------------------------------------------------------------------------- // // Methods // //-------------------------------------------------------------------------- /** * If Flex calls the LayoutManager.invalidateProperties() * method on this ILayoutManagerClient, then * this function is called when it's time to commit property values. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function validateProperties():void { invalidatePropertiesFlag = false; if (_listData) { var dg:DataGrid = DataGrid(_listData.owner); var column:DataGridColumn = dg.columns[_listData.columnIndex]; text = _listData.label; if (_data is DataGridColumn) wordWrap = dg.columnHeaderWordWrap(column); else wordWrap = dg.columnWordWrap(column); if (DataGrid(_listData.owner).variableRowHeight) multiline = true; var dataTips:Boolean = dg.showDataTips; if (column.showDataTips == true) dataTips = true; if (column.showDataTips == false) dataTips = false; if (dataTips) { 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; } } /** * If Flex calls the LayoutManager.invalidateSize() * method on this ILayoutManagerClient, then * this function is called when it's time to do measurements. * * @param recursive If true, call this method * on the object's children. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function validateSize(recursive:Boolean = false):void { invalidateSizeFlag = false; validateNow(); } /** * If Flex calls LayoutManager.invalidateDisplayList() * method on this ILayoutManagerClient, then * this function is called when it's time to update the display list. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function validateDisplayList():void { validateNow(); } /** * @copy mx.core.UIComponent#clearStyle() * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function clearStyle(styleProp:String):void { setStyle(styleProp, undefined); } /** * @inheritDoc * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function notifyStyleChangeInChildren( styleProp:String, recursive:Boolean):void { } /** * Sets up the inheritingStyles * and nonInheritingStyles objects * and their proto chains so that the getStyle() method can work. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function initProtoChain():void { styleChangedFlag = true; var classSelectors:Array = []; if (styleName) { if (styleName is CSSStyleDeclaration) { // Get the style sheet referenced by the styleName property classSelectors.push(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 var styleNames:Array = styleName.split(/\s+/); for (var c:int=0; c < styleNames.length; c++) { if (styleNames[c].length) { classSelectors.push(styleManager.getStyleDeclaration("." + styleNames[c])); } } } } // 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; var p:IStyleClient = parent as IStyleClient; if (p) { var inheritChain:Object = p.inheritingStyles; if (inheritChain == StyleProtoChain.STYLE_UNINITIALIZED) inheritChain = nonInheritChain; } 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); } // Next are the class selectors for (i = 0; i < classSelectors.length; i++) { var classSelector:CSSStyleDeclaration = classSelectors[i]; if (classSelector) { inheritChain = classSelector.addStyleToProtoChain(inheritChain, this); nonInheritChain = classSelector.addStyleToProtoChain(nonInheritChain, this); } } // 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 * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function regenerateStyleCache(recursive:Boolean):void { initProtoChain(); } /** * @inheritDoc * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function registerEffects(effects:Array /* of String */):void { } /** * @inheritDoc * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ 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.UIFTETextField") { 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. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function toolTipShowHandler(event:ToolTipEvent):void { var toolTip:IToolTip = event.toolTip; // We need to position the tooltip at same x coordinate, // center vertically and make sure it doesn't overlap the screen. // Call the helper function to handle this for us. var pt:Point = PopUpUtil.positionOverComponent(this, systemManager, toolTip.width, toolTip.height, height / 2); toolTip.move(pt.x, pt.y); } } }