1/* 2 SwitchTableView.m 3 4 Copyright (c) 2001 Pierre-Yves Rivaille 5 6 This library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Library General Public 8 License as published by the Free Software Foundation; either 9 version 2 of the License, or (at your option) any later version. 10 11 This library is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Library General Public License for more details. 15 16 You should have received a copy of the GNU Library General Public 17 License along with this library; see the file COPYING.LIB. 18 If not, write to the Free Software Foundation, 19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20*/ 21 22#include "SwitchTableView.h" 23 24#include "ExtendedTableColumn.h" 25 26// 27// 28// 29@implementation SwitchTableView 30 31- (void) mouseDown: (NSEvent *)theEvent 32{ 33 NSPoint location = [theEvent locationInWindow]; 34 NSTableColumn *tb; 35 36#ifdef MACOSX 37 int _clickedRow; 38 int _clickedColumn; 39 int _numberOfRows = [self frame].size.height / _rowHeight; 40 int _numberOfColumns = [_tableColumns count]; 41#endif 42 // 43 // Pathological case -- ignore mouse down 44 // 45 if ((_numberOfRows == 0) || (_numberOfColumns == 0)) 46 { 47 [super mouseDown: theEvent]; 48 return; 49 } 50 51 // Determine row and column which were clicked 52 location = [self convertPoint: location fromView: nil]; 53 _clickedRow = [self rowAtPoint: location]; 54 _clickedColumn = [self columnAtPoint: location]; 55 56 if (_clickedRow == -1 || _clickedColumn == -1) 57 return; 58 59 tb = [_tableColumns objectAtIndex: _clickedColumn]; 60 61 if ([tb shouldUseMouse] == YES) 62 { 63 NSApplication *theApp = [NSApplication sharedApplication]; 64 BOOL mouseUp = NO, done = NO; 65 NSEvent *e; 66 int oldActionMask; 67 NSPoint location; 68 unsigned int event_mask = NSLeftMouseDownMask | NSLeftMouseUpMask 69 | NSMouseMovedMask | NSLeftMouseDraggedMask 70 | NSRightMouseDraggedMask; 71 NSCell *mouseCell; 72 NSRect mouseCellFrame; 73 74 mouseCell = [[_tableColumns objectAtIndex: _clickedColumn] 75 dataCellForRow: _clickedRow]; 76 77 mouseCellFrame = [self frameOfCellAtColumn: _clickedColumn 78 row: _clickedRow]; 79 [mouseCell setObjectValue: [_dataSource tableView: self 80 objectValueForTableColumn: tb 81 row: _clickedRow]]; 82 if ([tb shouldUseAndSetState] == YES) 83 [mouseCell setState: [_dataSource tableView: self 84 stateForTableColumn: tb 85 row: _clickedRow]]; 86 87 if ([tb shouldUseTag] == YES) 88 [mouseCell setTag: [_dataSource tableView: self 89 tagForTableColumn: tb 90 row: _clickedRow]]; 91 92#ifdef MACOSX 93 if (_tvFlags.delegateWillDisplayCell) 94#else 95 if (_del_responds) 96#endif 97 { 98 [_delegate tableView: self willDisplayCell: mouseCell 99 forTableColumn: tb row: _clickedRow]; 100 } 101 102 if ([mouseCell isEnabled] == NO) 103 return; 104 105 106 107 if ([mouseCell isContinuous]) 108 oldActionMask = [mouseCell sendActionOn: 0]; 109 else 110 oldActionMask = [mouseCell sendActionOn: NSPeriodicMask]; 111 112 // [_window _captureMouse: self]; 113 114 e = theEvent; 115 while (!done) // loop until mouse goes up 116 { 117 location = [e locationInWindow]; 118 location = [self convertPoint: location fromView: nil]; 119 // ask the cell to track the mouse only 120 // if the mouse is within the cell 121 if (NSMouseInRect(location, mouseCellFrame, YES)) 122 { 123 [mouseCell highlight: YES 124 withFrame: mouseCellFrame 125 inView: self]; 126 [_window flushWindow]; 127 if ([mouseCell trackMouse: e 128 inRect: mouseCellFrame 129 ofView: self 130 untilMouseUp: /*[[mouseCell class] prefersTrackingUntilMouseUp]]*/NO]) 131 done = mouseUp = YES; 132 else 133 { 134 [mouseCell highlight: NO 135 withFrame: mouseCellFrame 136 inView: self]; 137 [_window flushWindow]; 138 } 139 } 140 141 if (done) 142 break; 143 144 e = [theApp nextEventMatchingMask: event_mask 145 untilDate: nil 146 inMode: NSEventTrackingRunLoopMode 147 dequeue: YES]; 148 if ([e type] == NSLeftMouseUp) 149 done = YES; 150 } 151 152 // [_window _releaseMouse: self]; 153 if (mouseUp) 154 { 155#ifdef MACOSX 156 [mouseCell setNextState]; 157#endif 158 if ([tb shouldUseAndSetState] == YES) 159 [_dataSource tableView: self 160 setState: [mouseCell state] 161 forTableColumn: tb 162 row: _clickedRow]; 163 164 // [cell setState: ![cell state]]; 165 [mouseCell highlight: NO 166 withFrame: mouseCellFrame 167 inView: self]; 168 [_window flushWindow]; 169 } 170 171 [mouseCell sendActionOn: oldActionMask]; 172 173 if (mouseUp) 174 { 175 SEL theAction; 176 theAction = [mouseCell action]; 177 if (theAction) 178 [NSApp sendAction: theAction 179 to: [mouseCell target] 180 from: mouseCell]; 181 } 182 return; 183 } 184 185 [super mouseDown: theEvent]; 186} 187 188 189// 190// 191// 192- (void)drawRow: (int)rowIndex clipRect: (NSRect)aRect 193{ 194 int startingColumn; 195 int endingColumn; 196 NSTableColumn *tb; 197 NSRect drawingRect; 198 NSCell *cell; 199 int i; 200#ifndef MACOSX 201 float x_pos; 202#endif 203 204 if (_dataSource == nil) 205 { 206 return; 207 } 208 209#ifdef MACOSX 210 startingColumn = [self columnAtPoint: NSMakePoint(NSMinX(aRect), NSMinY(aRect))]; 211#else 212 /* Using columnAtPoint: here would make it called twice per row per drawn 213 rect - so we avoid it and do it natively */ 214 215 /* Determine starting column as fast as possible */ 216 x_pos = NSMinX (aRect); 217 i = 0; 218 while ((x_pos > _columnOrigins[i]) && (i < _numberOfColumns)) 219 { 220 i++; 221 } 222 startingColumn = (i - 1); 223 224 if (startingColumn == -1) 225 startingColumn = 0; 226#endif 227 228 229#ifdef MACOSX 230 endingColumn = [self columnAtPoint: NSMakePoint(NSMaxX(aRect), NSMinY(aRect))]; 231#else 232 /* Determine ending column as fast as possible */ 233 x_pos = NSMaxX (aRect); 234 // Nota Bene: we do *not* reset i 235 while ((x_pos > _columnOrigins[i]) && (i < _numberOfColumns)) 236 { 237 i++; 238 } 239 endingColumn = (i - 1); 240 241 if (endingColumn == -1) 242 endingColumn = _numberOfColumns - 1; 243#endif 244 245 246 /* Draw the row between startingColumn and endingColumn */ 247 for (i = startingColumn; i <= endingColumn; i++) 248 { 249#ifdef MACOSX 250 if (i != _editingColumn || rowIndex != _editingRow) 251#else 252 if (i != _editedColumn || rowIndex != _editedRow) 253#endif 254 { 255 tb = [_tableColumns objectAtIndex: i]; 256 cell = [tb dataCellForRow: rowIndex]; 257#ifdef MACOSX 258 if (_tvFlags.delegateWillDisplayCell) 259#else 260 if (_del_responds) 261#endif 262 { 263 [_delegate tableView: self willDisplayCell: cell 264 forTableColumn: tb row: rowIndex]; 265 } 266 [cell setObjectValue: [_dataSource tableView: self 267 objectValueForTableColumn: tb 268 row: rowIndex]]; 269 if ([tb shouldUseAndSetState] == YES) 270 [cell setState: [_dataSource tableView: self 271 stateForTableColumn: tb 272 row: rowIndex]]; 273 drawingRect = [self frameOfCellAtColumn: i 274 row: rowIndex]; 275 [cell drawWithFrame: drawingRect inView: self]; 276 } 277 } 278} 279 280@end 281