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 sc_require('views/table');
  9 
 10 
 11 SC.TableHeaderView = SC.View.extend({
 12 
 13   classNames: ['sc-table-header'],
 14 
 15   displayProperties: ['sortState', 'isInDragMode'],
 16 
 17   acceptsFirstResponder: YES,
 18 
 19   isInDragMode: NO,
 20 
 21   hasHorizontalScroller: NO,
 22   hasVerticalScroller: NO,
 23 
 24   childViews: ['dragModeView'],
 25 
 26 
 27   /**
 28     The view that is visible when the column is in drag mode.
 29   */
 30   dragModeView: SC.ListView.extend({
 31     isVisible: NO,
 32 
 33     layout: { left: 0, right: 0, bottom: 0 },
 34 
 35     init: function() {
 36       sc_super();
 37 
 38       var tableHeaderView = this.get('parentView');
 39 
 40       if (tableHeaderView) {
 41         tableHeaderView.addObserver('isInDragMode', this,
 42             '_scthv_dragModeDidChange');
 43       }
 44 
 45     },
 46 
 47     _scthv_dragModeDidChange: function() {
 48       // var isInDragMode = this.get('tableHeaderView').get('isInDragMode');
 49       // this.set('isVisible', isInDragMode);
 50     }
 51   }),
 52 
 53   /**
 54     The SC.TableColumn object this header cell is bound to.
 55   */
 56   column:  null,
 57 
 58   render: function(context, firstTime) {
 59     var column = this.get('column'), icon = column.get('icon'), html;
 60     var span = context.begin('span');
 61     if (icon) {
 62       html = '<img src="%@" class="icon" />'.fmt(icon);
 63       span.push(html);
 64     } else {
 65       span.push(this.get('label'));
 66     }
 67     span.end();
 68   },
 69 
 70   // ========================================================
 71   // = For the column we look after, set up some observers. =
 72   // ========================================================
 73   init: function() {
 74     sc_super();
 75 
 76     var column = this.get('column');
 77     column.addObserver('width',     this, '_scthv_layoutDidChange');
 78     column.addObserver('maxWidth',  this, '_scthv_layoutDidChange');
 79     column.addObserver('minWidth',  this, '_scthv_layoutDidChange');
 80     column.addObserver('sortState', this, '_scthv_sortStateDidChange');
 81     column.addObserver('tableContent', this, '_scthv_tableContentDidChange');
 82 
 83     // var tableContent = column.get('tableContent');
 84     // var columnContent = this._scthv_columnContentFromTableContent(tableContent);
 85     // this.set('content', columnContent);
 86   },
 87 
 88   /**
 89     The sortState of the header view's column.
 90   */
 91   sortState: function() {
 92     return this.get('column').get('sortState');
 93   }.property(),
 94 
 95   mouseDown: function(evt) {
 96     var tableView = this.get('tableView');
 97     return tableView ? tableView.mouseDownInTableHeaderView(evt, this) :
 98      sc_super();
 99   },
100 
101   mouseUp: function(evt) {
102     var tableView = this.get('tableView');
103     return tableView ? tableView.mouseUpInTableHeaderView(evt, this) :
104      sc_super();
105   },
106 
107   mouseDragged: function(evt) {
108     var tableView = this.get('tableView');
109     return tableView ? tableView.mouseDraggedInTableHeaderView(evt, this) :
110      sc_super();
111   },
112 
113   _scthv_dragViewForHeader: function() {
114     var dragLayer = this.get('layer').cloneNode(true);
115     var view = SC.View.create({ layer: dragLayer, parentView: this });
116 
117     // cleanup weird stuff that might make the drag look out of place
118     SC.$(dragLayer).css('backgroundColor', 'transparent')
119       .css('border', 'none')
120       .css('top', 0).css('left', 0);
121 
122     return view;
123   },
124 
125   _scthv_enterDragMode: function() {
126     this.set('isInDragMode', YES);
127   },
128 
129   _scthv_exitDragMode: function() {
130     this.set('isInDragMode', NO);
131   },
132 
133   // _scthv_hideViewInDragMode: function() {
134   //   var shouldBeVisible = !this.get('isInDragMode'), layer = this.get('layer');
135   //   console.log('should be visible: %@'.fmt(!this.get('isInDragMode')));
136   //   SC.RunLoop.begin();
137   //   SC.$(layer).css('display', shouldBeVisible ? 'block' : 'none');
138   //   SC.RunLoop.end();
139   // }.observes('isInDragMode'),
140 
141   // _scthv_setupDragMode: function() {
142   //   var isInDragMode = this.get('isInDragMode');
143   //   if (isInDragMode) {
144   //     });
145   //   } else {
146   //     //
147   //   }
148   //
149   //
150   // }.observes('isInDragMode'),
151 
152   _scthv_dragModeViewDidChange: function() {
153     var dragModeView = this.get('dragModeView');
154     if (dragModeView && dragModeView.set) {
155       dragModeView.set('tableHeadView', this);
156       dragModeView.set('tableView', this.get('tableView'));
157     }
158   }.observes('dragModeView'),
159 
160   _scthv_layoutDidChange: function(sender, key, value, rev) {
161     var pv = this.get('parentView');
162     pv.invokeOnce(pv.layoutChildViews);
163 
164     // Tell the container view how tall the header is so that it can adjust
165     // itself accordingly.
166     var layout = this.get('layout');
167     //this.get('dragModeView').adjust('top', layout.height);
168   },
169 
170   // When our column's tableContent property changes, we need to go back and get our column content
171   _scthv_tableContentDidChange: function() {
172     var tableContent = this.get('column').get('tableContent');
173     var columnContent = this.get('parentView')._scthv_columnContentFromTableContent(tableContent, this.get('columnIndex'));
174     this.set('content', columnContent);
175   },
176 
177   _scthv_sortStateDidChange: function() {
178     SC.RunLoop.begin();
179     var sortState  = this.get('column').get('sortState');
180     var classNames = this.get('classNames');
181 
182     classNames.removeObject('sc-table-header-sort-asc');
183     classNames.removeObject('sc-table-header-sort-desc');
184     classNames.removeObject('sc-table-header-sort-active');
185 
186     if (sortState !== null) {
187       classNames.push('sc-table-header-sort-active');
188     }
189 
190     if (sortState === SC.SORT_ASCENDING) {
191       classNames.push('sc-table-header-sort-asc');
192     }
193 
194     if (sortState === SC.SORT_DESCENDING) {
195       classNames.push('sc-table-header-sort-desc');
196     }
197 
198     // TODO: Figure out why it's not enough to simply call
199     // `displayDidChange` here.
200     this.displayDidChange();
201     this.invokeOnce('updateLayer');
202     SC.RunLoop.end();
203   }
204 });
205