1 // Copyright: ©2006-2010 Sprout Systems, Inc. and contributors. 2 // Portions ©2008-2010 Apple Inc. All rights reserved. 3 // License: Licensed under MIT license (see license.js) 4 // ========================================================================== 5 6 /** 7 * Binds a menu view to an owning SC.SelectView, and checks selected items. 8 * 9 * @mixin 10 * 11 */ 12 SC.SelectViewMenu = { 13 /** 14 The SelectView to bind to. 15 16 @property 17 @type {SC.SelectView} 18 @default null 19 */ 20 selectView: null, 21 22 // 23 // CODE TO MAKE ITEMS BE CHECKED WHEN SELECTED: 24 // 25 26 /** 27 The current value of the SelectView. 28 29 @property 30 @default null 31 */ 32 value: null, 33 valueBinding: '.selectView.value', 34 35 36 /** 37 @private 38 Invalidates menu items' isChecked property when the selectView's value changes. 39 */ 40 valueDidChange: function() { 41 var items = this.get('menuItemViews'), idx, len = items.length, item; 42 for (idx = 0; idx < len; idx++) { 43 // if the item currently is checked, or if it _should_ be checked, we need to 44 // invalidate the isChecked property. 45 item = items[idx]; 46 if (item._lastIsChecked) { 47 item.notifyPropertyChange('isChecked'); 48 } 49 50 if (item.get('isChecked')) { 51 item.notifyPropertyChange('isChecked'); 52 } 53 } 54 }.observes('value'), 55 56 /** 57 An overridden MenuItemView to create for each menu item that makes itself checked if 58 it is selected. 59 60 @property 61 @type {SC.MenuItemView} 62 @default SC.MenuItemView subclass 63 */ 64 exampleView: SC.AutoResizingMenuItemView.extend({ 65 isChecked: function() { 66 var selectView = this.getPath('parentMenu.selectView'); 67 68 // _lastIsChecked is used by the SelectViewMenu mixin above to determine whether 69 // the isChecked property needs to be invalidated. 70 this._lastIsChecked = selectView.isValueEqualTo(this.get('content')); 71 72 return this._lastIsChecked; 73 }.property(), 74 75 displayProperties: ['isChecked'] 76 }), 77 78 // 79 // CODE TO BIND TO SELECTVIEW PROPERTIES 80 // 81 82 /** @private */ 83 _svm_bindToProperties: [ 84 { from: 'displayItems', to: 'items' }, 85 { from: '_itemTitleKey', to: 'itemTitleKey' }, 86 { from: '_itemIsEnabledKey', to: 'itemIsEnabledKey' }, 87 { from: '_itemValueKey', to: 'itemValueKey' }, 88 'itemIconKey', 'itemHeightKey', 'itemSubMenuKey', 'itemSeparatorKey', 89 'itemTargetKey', 'itemActionKey', 'itemCheckboxKey', 'itemShortCutKey', 90 'itemKeyEquivalentKey', 'itemDisableMenuFlashKey', 'minimumMenuWidth', 91 'target', 'action', 92 'preferType', 'preferMatrix' 93 ], 94 95 /** @private */ 96 _svm_setupBindings: function() { 97 var bindTo = this.get('selectView'); 98 if (!bindTo) { 99 return; 100 } 101 102 var props = this._svm_bindToProperties, idx, len = props.length, from, to; 103 104 for (idx = 0; idx < len; idx++) { 105 from = to = props[idx]; 106 107 if (SC.typeOf(from) === SC.T_HASH) { 108 from = from.from; 109 to = to.to; 110 } 111 this[to + 'Binding'] = this.bind(to, bindTo, from); 112 } 113 114 this._svm_isBoundTo = bindTo; 115 }, 116 117 /** @private */ 118 _svm_clearBindings: function() { 119 var boundTo = this._svm_isBoundTo; 120 if (!boundTo) { 121 return; 122 } 123 124 var props = this._svm_bindToProperties, idx, len = props.length, key; 125 126 for (idx = 0; idx < len; idx++) { 127 key = props[idx]; 128 129 if (SC.typeOf(from) === SC.T_HASH) { 130 key = key.to; 131 } 132 this[key + 'Binding'].disconnect(); 133 } 134 }, 135 136 /** @private */ 137 _svm_selectViewDidChange: function() { 138 this._svm_clearBindings(); 139 this._svm_setupBindings(); 140 }.observes('selectView'), 141 142 /** @private */ 143 initMixin: function() { 144 this._svm_setupBindings(); 145 }, 146 147 /** @private */ 148 destroyMixin: function() { 149 this._svm_clearBindings(); 150 } 151 }; 152 153 154