1 // ==========================================================================
  2 // Project:   SproutCore - JavaScript Application Framework
  3 // Copyright: ©2006-2010 Sprout Systems, Inc. and contributors.
  4 //            Portions ©2008-2010 Apple Inc. All rights reserved.
  5 // License:   Licensed under MIT license (see license.js)
  6 // ==========================================================================
  7 
  8 /**
  9   @class
 10   Extends SC.MenuItemView to support auto resize.
 11 */
 12 
 13 SC.AutoResizingMenuItemView = SC.MenuItemView.extend(SC.AutoResize,
 14 /** @scope SC.AutoResizingMenuItemView.prototype */ {
 15 
 16   //
 17   // For automatic resizing, if enabled (to be enabled by parent menu)
 18   //
 19   /**
 20     The item view is capable of automatic resizing.
 21     
 22     @private
 23     @property
 24     @type {Boolean}
 25   */
 26   supportsAutoResize: YES,
 27 
 28   /**
 29     The menu item should NOT change its own width and height.
 30     
 31     @private
 32     @property
 33     @type {Boolean}
 34   */
 35   shouldAutoResize: NO,
 36   
 37   /**
 38     If YES, the menu item will measure its width and height so that the menu
 39     can automatically resize itself. This is usually set by the parent menu.
 40     
 41     @property
 42     @type {Boolean}
 43     @default NO
 44   */
 45   shouldMeasureSize: NO,
 46 
 47   // NOTE: this property could come from the theme at some point, but MenuItemView
 48   // would have to be migrated to render delegates first. MenuPane adds the
 49   // necessary padding for now.
 50   autoResizePadding: 0,
 51   
 52   /** @private */
 53   autoResizeText: function() {
 54     return this.get('title');
 55   }.property('title'),
 56 
 57   /** @private */
 58   autoResizeLayer: function() {
 59     return this.$('.value')[0];
 60   }.property('layer').cacheable(),
 61   
 62   /** 
 63     @private
 64     The batch resize id is computed to be "good enough." It is unlikely that
 65     multiple menus of different size will need to resize at the same time, but
 66     we guard against this a little bit by giving it a name based on the menu's guid.
 67     
 68     This won't cover cases where the menu has items of multiple sizes, but that's
 69     an edge case that can address the issue by overriding batchResizeId to null.
 70   */
 71   batchResizeId: function() {
 72     return 'menu-' + SC.guidFor(this.parentMenu);
 73   }.property().cacheable(),
 74 
 75   /**
 76    * @private
 77    * When we render, we recreate all of the DOM, including the element that gets measured.
 78    * This is a problem because our autoResizeLayer changes. So, we must invalidate that
 79    * layer whenever we re-render.
 80    *
 81    * We need to move menu item rendering into a render delegate. When this happens, there
 82    * are a few ways we could do it:
 83    *
 84    * - Give render delegate method to find clientWidth and return it: 
 85    *   getMenuItemTitleWidth(dataSource, $)
 86    *
 87    * - Make render delegate provide the autoResizeLayer:
 88    *   In this case, the autoResizeLayer might be a computed property that we invalidate
 89    *   on didUpdateLayer, and that calls a method like getAutoResizeLayer. Alternatively,
 90    *   if render delegate properties are added, we could make this one of those, but it
 91    *   would need some way to access the DOM. Maybe data sources can have $ properties or
 92    *   methods? Maybe a jQuery property/method?
 93   */
 94   didUpdateLayer: function() {
 95     this.notifyPropertyChange('autoResizeLayer');
 96     this.scheduleMeasurement();
 97   }
 98 
 99 }) ;
100 
101 
102