1//////////////////////////////////////////////////////////////////////////////// 2// 3// ADOBE SYSTEMS INCORPORATED 4// Copyright 2004-2007 Adobe Systems Incorporated 5// All Rights Reserved. 6// 7// NOTICE: Adobe permits you to use, modify, and distribute this file 8// in accordance with the terms of the license agreement accompanying it. 9// 10//////////////////////////////////////////////////////////////////////////////// 11 12package mx.controls.listClasses 13{ 14 15import flash.display.DisplayObject; 16import flash.geom.Point; 17import flash.geom.Rectangle; 18 19import mx.core.IDataRenderer; 20import mx.core.IFlexDisplayObject; 21import mx.core.IFlexModuleFactory; 22import mx.core.IFontContextComponent; 23import mx.core.IToolTip; 24import mx.core.IUITextField; 25import mx.core.UIComponent; 26import mx.core.UITextField; 27import mx.core.mx_internal; 28import mx.events.FlexEvent; 29import mx.events.InterManagerRequest; 30import mx.events.ToolTipEvent; 31import mx.managers.ISystemManager; 32import mx.utils.PopUpUtil; 33 34use namespace mx_internal; 35 36//-------------------------------------- 37// Events 38//-------------------------------------- 39 40/** 41 * Dispatched when the <code>data</code> property changes. 42 * 43 * <p>When you use a component as an item renderer, 44 * the <code>data</code> property contains the data to display. 45 * You can listen for this event and update the component 46 * when the <code>data</code> property changes.</p> 47 * 48 * @eventType mx.events.FlexEvent.DATA_CHANGE 49 * 50 * @langversion 3.0 51 * @playerversion Flash 9 52 * @playerversion AIR 1.1 53 * @productversion Flex 3 54 */ 55[Event(name="dataChange", type="mx.events.FlexEvent")] 56 57//-------------------------------------- 58// Styles 59//-------------------------------------- 60 61/** 62 * Text color of a component label. 63 * 64 * The default value for the Halo theme is <code>0x0B333C</code>. 65 * The default value for the Spark theme is <code>0x000000</code>. 66 * 67 * @langversion 3.0 68 * @playerversion Flash 9 69 * @playerversion AIR 1.1 70 * @productversion Flex 3 71 */ 72[Style(name="color", type="uint", format="Color", inherit="yes")] 73 74/** 75 * Text color of the component if it is disabled. 76 * 77 * @default 0xAAB3B3 78 * 79 * @langversion 3.0 80 * @playerversion Flash 9 81 * @playerversion AIR 1.1 82 * @productversion Flex 3 83 */ 84[Style(name="disabledColor", type="uint", format="Color", inherit="yes")] 85 86/** 87 * The ListItemRenderer class defines the default item renderer 88 * for a List control. 89 * By default, the item renderer draws the text associated 90 * with each item in the list, and an optional icon. 91 * 92 * <p>You can override the default item renderer 93 * by creating a custom item renderer.</p> 94 * 95 * @see mx.controls.List 96 * @see mx.core.IDataRenderer 97 * @see mx.controls.listClasses.IDropInListItemRenderer 98 * 99 * @langversion 3.0 100 * @playerversion Flash 9 101 * @playerversion AIR 1.1 102 * @productversion Flex 3 103 */ 104public class ListItemRenderer extends UIComponent 105 implements IDataRenderer, 106 IDropInListItemRenderer, IListItemRenderer, 107 IFontContextComponent 108{ 109 include "../../core/Version.as"; 110 111 //-------------------------------------------------------------------------- 112 // 113 // Constructor 114 // 115 //-------------------------------------------------------------------------- 116 117 /** 118 * Constructor. 119 * 120 * @langversion 3.0 121 * @playerversion Flash 9 122 * @playerversion AIR 1.1 123 * @productversion Flex 3 124 */ 125 public function ListItemRenderer() 126 { 127 super(); 128 129 addEventListener(ToolTipEvent.TOOL_TIP_SHOW, toolTipShowHandler); 130 } 131 132 //-------------------------------------------------------------------------- 133 // 134 // Variables 135 // 136 //-------------------------------------------------------------------------- 137 138 /** 139 * @private 140 */ 141 private var listOwner:ListBase; 142 143 //-------------------------------------------------------------------------- 144 // 145 // Overridden properties: UIComponent 146 // 147 //-------------------------------------------------------------------------- 148 149 //---------------------------------- 150 // baselinePosition 151 //---------------------------------- 152 153 /** 154 * @private 155 * The baselinePosition of a ListItemRenderer is calculated 156 * for its label. 157 */ 158 override public function get baselinePosition():Number 159 { 160 if (!validateBaselinePosition()) 161 return NaN; 162 163 return label.y + label.baselinePosition; 164 } 165 166 //-------------------------------------------------------------------------- 167 // 168 // Properties 169 // 170 //-------------------------------------------------------------------------- 171 172 //---------------------------------- 173 // data 174 //---------------------------------- 175 176 /** 177 * @private 178 * Storage for the data property. 179 */ 180 private var _data:Object; 181 182 [Bindable("dataChange")] 183 184 /** 185 * The implementation of the <code>data</code> property 186 * as defined by the IDataRenderer interface. 187 * When set, it stores the value and invalidates the component 188 * to trigger a relayout of the component. 189 * 190 * @see mx.core.IDataRenderer 191 * 192 * @langversion 3.0 193 * @playerversion Flash 9 194 * @playerversion AIR 1.1 195 * @productversion Flex 3 196 */ 197 public function get data():Object 198 { 199 return _data; 200 } 201 202 /** 203 * @private 204 */ 205 public function set data(value:Object):void 206 { 207 _data = value; 208 209 invalidateProperties(); 210 211 dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE)); 212 } 213 214 //---------------------------------- 215 // fontContext 216 //---------------------------------- 217 218 /** 219 * @inheritDoc 220 * 221 * @langversion 3.0 222 * @playerversion Flash 9 223 * @playerversion AIR 1.1 224 * @productversion Flex 3 225 */ 226 public function get fontContext():IFlexModuleFactory 227 { 228 return moduleFactory; 229 } 230 231 /** 232 * @private 233 */ 234 public function set fontContext(moduleFactory:IFlexModuleFactory):void 235 { 236 this.moduleFactory = moduleFactory; 237 } 238 239 //---------------------------------- 240 // icon 241 //---------------------------------- 242 243 /** 244 * The internal IFlexDisplayObject that displays the icon in this renderer. 245 * 246 * @langversion 3.0 247 * @playerversion Flash 9 248 * @playerversion AIR 1.1 249 * @productversion Flex 3 250 */ 251 protected var icon:IFlexDisplayObject; 252 253 //---------------------------------- 254 // label 255 //---------------------------------- 256 257 /** 258 * The internal UITextField that displays the text in this renderer. 259 * 260 * @langversion 3.0 261 * @playerversion Flash 9 262 * @playerversion AIR 1.1 263 * @productversion Flex 3 264 */ 265 protected var label:IUITextField; 266 267 //---------------------------------- 268 // listData 269 //---------------------------------- 270 271 /** 272 * @private 273 * Storage for the listData property. 274 */ 275 private var _listData:ListData; 276 277 [Bindable("dataChange")] 278 279 /** 280 * The implementation of the <code>listData</code> property 281 * as defined by the IDropInListItemRenderer interface. 282 * 283 * @see mx.controls.listClasses.IDropInListItemRenderer 284 * 285 * @langversion 3.0 286 * @playerversion Flash 9 287 * @playerversion AIR 1.1 288 * @productversion Flex 3 289 */ 290 public function get listData():BaseListData 291 { 292 return _listData; 293 } 294 295 /** 296 * @private 297 */ 298 public function set listData(value:BaseListData):void 299 { 300 _listData = ListData(value); 301 302 invalidateProperties(); 303 } 304 305 //-------------------------------------------------------------------------- 306 // 307 // Overridden methods: UIComponent 308 // 309 //-------------------------------------------------------------------------- 310 311 /** 312 * @private 313 */ 314 override protected function createChildren():void 315 { 316 super.createChildren(); 317 318 if (!label) 319 { 320 label = IUITextField(createInFontContext(UITextField)); 321 label.styleName = this; 322 addChild(DisplayObject(label)); 323 } 324 } 325 326 /** 327 * @private 328 * Apply the data and listData. 329 * Create an instance of the icon if specified, 330 * and set the text into the text field. 331 */ 332 override protected function commitProperties():void 333 { 334 super.commitProperties(); 335 336 var childIndex:int = -1; 337 if (hasFontContextChanged() && label != null) 338 { 339 childIndex = getChildIndex(DisplayObject(label)); 340 removeChild(DisplayObject(label)); 341 label = null; 342 } 343 344 if (!label) 345 { 346 label = IUITextField(createInFontContext(UITextField)); 347 label.styleName = this; 348 349 if (childIndex == -1) 350 addChild(DisplayObject(label)); 351 else 352 addChildAt(DisplayObject(label), childIndex); 353 } 354 355 if (icon) 356 { 357 removeChild(DisplayObject(icon)); 358 icon = null; 359 } 360 361 if (_data != null) 362 { 363 listOwner = ListBase(_listData.owner); 364 365 if (_listData.icon) 366 { 367 var iconClass:Class = _listData.icon; 368 icon = new iconClass(); 369 370 addChild(DisplayObject(icon)); 371 } 372 373 label.text = _listData.label ? _listData.label : " "; 374 label.multiline = listOwner.variableRowHeight; 375 label.wordWrap = listOwner.wordWrap; 376 377 if (listOwner.showDataTips) 378 { 379 if (label.textWidth > label.width || 380 listOwner.dataTipFunction != null) 381 { 382 toolTip = listOwner.itemToDataTip(_data); 383 } 384 else 385 { 386 toolTip = null; 387 } 388 } 389 else 390 { 391 toolTip = null; 392 } 393 } 394 else 395 { 396 label.text = " "; 397 toolTip = null; 398 } 399 } 400 401 /** 402 * @private 403 */ 404 override protected function measure():void 405 { 406 super.measure(); 407 408 var w:Number = 0; 409 410 if (icon) 411 w = icon.measuredWidth; 412 413 // Guarantee that label width isn't zero 414 // because it messes up ability to measure. 415 if (label.width < 4 || label.height < 4) 416 { 417 label.width = 4; 418 label.height = 16; 419 } 420 421 if (isNaN(explicitWidth)) 422 { 423 w += label.getExplicitOrMeasuredWidth(); 424 measuredWidth = w; 425 measuredHeight = label.getExplicitOrMeasuredHeight(); 426 } 427 else 428 { 429 measuredWidth = explicitWidth; 430 label.setActualSize(Math.max(explicitWidth - w, 4), label.height); 431 measuredHeight = label.getExplicitOrMeasuredHeight(); 432 if (icon && icon.measuredHeight > measuredHeight) 433 measuredHeight = icon.measuredHeight; 434 } 435 } 436 437 /** 438 * @private 439 */ 440 override protected function updateDisplayList(unscaledWidth:Number, 441 unscaledHeight:Number):void 442 { 443 super.updateDisplayList(unscaledWidth, unscaledHeight); 444 445 var startX:Number = 0; 446 447 if (icon) 448 { 449 icon.x = startX; 450 startX = icon.x + icon.measuredWidth; 451 icon.setActualSize(icon.measuredWidth, icon.measuredHeight); 452 } 453 454 label.x = startX; 455 label.setActualSize(unscaledWidth - startX, measuredHeight); 456 457 var verticalAlign:String = getStyle("verticalAlign"); 458 if (verticalAlign == "top") 459 { 460 label.y = 0; 461 if (icon) 462 icon.y = 0; 463 } 464 else if (verticalAlign == "bottom") 465 { 466 label.y = unscaledHeight - label.height + 2; // 2 for gutter 467 if (icon) 468 icon.y = unscaledHeight - icon.height; 469 } 470 else 471 { 472 label.y = (unscaledHeight - label.height) / 2; 473 if (icon) 474 icon.y = (unscaledHeight - icon.height) / 2; 475 } 476 477 var labelColor:Number; 478 479 if (data && parent) 480 { 481 if (!enabled) 482 labelColor = getStyle("disabledColor"); 483 else if (listOwner.isItemHighlighted(listData.uid)) 484 labelColor = getStyle("textRollOverColor"); 485 else if (listOwner.isItemSelected(listData.uid)) 486 labelColor = getStyle("textSelectedColor"); 487 else 488 labelColor = getStyle("color"); 489 490 label.setColor(labelColor); 491 } 492 } 493 494 495 //-------------------------------------------------------------------------- 496 // 497 // Event handlers 498 // 499 //-------------------------------------------------------------------------- 500 501 /** 502 * Positions the ToolTip object. 503 * 504 * @param The Event object. 505 * 506 * @langversion 3.0 507 * @playerversion Flash 9 508 * @playerversion AIR 1.1 509 * @productversion Flex 3 510 */ 511 protected function toolTipShowHandler(event:ToolTipEvent):void 512 { 513 var toolTip:IToolTip = event.toolTip; 514 515 // We need to position the tooltip at same x coordinate, 516 // center vertically and make sure it doesn't overlap the screen. 517 // Call the helper function to handle this for us. 518 var pt:Point = PopUpUtil.positionOverComponent(DisplayObject(label), 519 systemManager, 520 toolTip.width, 521 toolTip.height, 522 height / 2); 523 toolTip.move(pt.x, pt.y); 524 } 525 526 /** 527 * @private 528 */ 529 mx_internal function getLabel():IUITextField 530 { 531 return label; 532 } 533 534 535} 536 537} 538