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