1 // ========================================================================== 2 // Project: SproutCore - JavaScript Application Framework 3 // Copyright: ©2006-2011 Strobe Inc. and contributors. 4 // Portions ©2008-2011 Apple Inc. All rights reserved. 5 // License: Licensed under MIT license (see license.js) 6 // ========================================================================== 7 8 9 /** 10 An instance of this controller is created for every page where designers 11 are involved. The Designer's themselves will register with the 12 controller so that you can hook to the controller to manage the views and 13 their editors. 14 15 Among other things, this controller implements global selection support for 16 the designers. 17 18 @extends SC.Object 19 @since SproutCore 1.0 20 */ 21 SC.PageDesignController = SC.Object.extend({ 22 23 isPageDesignController: YES, 24 25 // .......................................................... 26 // SELECTION 27 // 28 29 /** The current view builder selection. */ 30 selection: null, 31 32 /** 33 Updates the selection either by adding the item or by resetting the 34 selection. Calling this method with no parameters will reset the 35 selection. 36 37 The passed selection must be a Designer object. 38 */ 39 select: function(sel, extend) { 40 var base = this.get('selection'); 41 if (!base || !extend || !base.contains(sel)) { 42 base = (!extend || !base) ? SC.CoreSet.create() : base.copy(); 43 base.add(sel); 44 this.set('selection', base.freeze()) ; 45 //make the designPane the firstResponder 46 SC.designPage.getPath('designMainPane.container').becomeFirstResponder(); 47 } 48 return this ; 49 }, 50 51 /** 52 Removes the passed items from the current selection. 53 54 The passed selection must be a Designer object. 55 */ 56 deselect: function(sel) { 57 58 var base = this.get('selection'); 59 if (base && base.contains(sel)) { 60 base = base.copy(); 61 base.remove(sel); 62 this.set('selection', base.freeze()); 63 } 64 return this; 65 }, 66 /** 67 Invoked whenever the selection changes. Updates the selection states 68 on the old and new views. 69 */ 70 selectionDidChange: function() { 71 var sel = this.get('selection'), 72 oldSel = this._selection ; 73 74 // save old selection for next time 75 this._selection = sel ; 76 77 // set the isSelected state on new selection. 78 if (sel) sel.setEach('designIsSelected', YES); 79 80 // remove the isSelected state for old selection not in new selection. 81 if (oldSel) { 82 oldSel.forEach(function(s){ 83 if (!sel || !sel.contains(s)) s.set('designIsSelected', NO); 84 }, this); 85 } 86 87 }.observes('selection'), 88 89 90 /** 91 Called by a view to reposition the current selection during a mouse 92 drag. 93 */ 94 repositionSelection: function(evt, info) { 95 var sel = this.get('selection'); 96 if (sel) sel.invoke('mouseReposition', evt, info); 97 }, 98 99 /** 100 Called by a view to prepare all views in selection for repositioning 101 */ 102 prepareReposition: function(info) { 103 var sel = this.get('selection'); 104 if (sel) sel.invoke('prepareReposition', info); 105 }, 106 /** 107 removes all views in the selection from their parent view 108 */ 109 deleteSelection: function(){ 110 var sel = this.get('selection'), first, parentView; 111 112 if(sel && sel.get('length') > 0){ 113 //TODO: delete multi selection 114 //this.beginPropertyChanges(); 115 //while(sel.get('length') > 0){ 116 first = sel.firstObject(); 117 this.deselect(first); 118 first = first.get('view'); 119 parentView = first.get('parentView'); 120 first.removeFromParent(); 121 if(parent.displayDidChange) parent.displayDidChange(); 122 first = null; 123 //} 124 //this.endPropertyChanges(); 125 } 126 }, 127 128 129 // .......................................................... 130 // DESIGNERS 131 // 132 133 /** All of the designers on the current page. */ 134 designers: null, 135 136 /** 137 Called by each designer when it is created to register itself with the 138 controller. You can use this to know which designers are currently in 139 the document to delete them as needed. 140 */ 141 registerDesigner: function(designer) { 142 this.get('designers').add(designer); 143 }, 144 145 // .......................................................... 146 // ROOT DESIGNER 147 // 148 rootDesigner: null, 149 150 makeRootDesigner: function(designer){ 151 var currRoot = this.get('rootDesigner'); 152 153 if(currRoot) currRoot.set('isRootDesigner', NO); 154 155 this.deselect(designer); 156 designer.set('isRootDesigner', YES); 157 designer.set('prevRootDesigner', currRoot); 158 //TODO: allow greenhouse to highlight the root view! 159 this.set('rootDesigner', designer); 160 }, 161 162 163 // .......................................................... 164 // INTERNAL SUPPORT 165 // 166 init: function() { 167 this.designers = SC.Set.create(); 168 this.sel = []; 169 sc_super(); 170 } 171 172 }) ; 173