comparison dwt/widgets/Table.d @ 45:d8635bb48c7c

Merge with SWT 3.5
author Jacob Carlborg <doob@me.com>
date Mon, 01 Dec 2008 17:07:00 +0100
parents e831403a80a9
children cfa563df4fdd
comparison
equal deleted inserted replaced
44:ca5e494f2bbf 45:d8635bb48c7c
1 /******************************************************************************* 1 /*******************************************************************************
2 * Copyright (c) 2000, 2007 IBM Corporation and others. 2 * Copyright (c) 2000, 2008 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials 3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0 4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at 5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html 6 * http://www.eclipse.org/legal/epl-v10.html
7 * 7 *
10 *******************************************************************************/ 10 *******************************************************************************/
11 module dwt.widgets.Table; 11 module dwt.widgets.Table;
12 12
13 import dwt.dwthelper.utils; 13 import dwt.dwthelper.utils;
14 14
15
16 import dwt.DWT; 15 import dwt.DWT;
17 import dwt.DWTException; 16 import dwt.DWTException;
17 import dwt.accessibility.ACC;
18 import dwt.events.SelectionEvent; 18 import dwt.events.SelectionEvent;
19 import dwt.events.SelectionListener; 19 import dwt.events.SelectionListener;
20 import dwt.graphics.Color; 20 import dwt.graphics.Color;
21 import dwt.graphics.Font; 21 import dwt.graphics.Font;
22 import dwt.graphics.GC; 22 import dwt.graphics.GC;
23 import dwt.graphics.GCData;
23 import dwt.graphics.Image; 24 import dwt.graphics.Image;
24 import dwt.graphics.Point; 25 import dwt.graphics.Point;
25 import dwt.graphics.Rectangle; 26 import dwt.graphics.Rectangle;
27 import dwt.internal.cocoa.NSArray;
28 import dwt.internal.cocoa.NSBezierPath;
26 import dwt.internal.cocoa.NSBrowserCell; 29 import dwt.internal.cocoa.NSBrowserCell;
27 import dwt.internal.cocoa.NSButtonCell; 30 import dwt.internal.cocoa.NSButtonCell;
28 import dwt.internal.cocoa.NSCell; 31 import dwt.internal.cocoa.NSColor;
32 import dwt.internal.cocoa.NSColorSpace;
33 import dwt.internal.cocoa.NSDictionary;
34 import dwt.internal.cocoa.NSEvent;
35 import dwt.internal.cocoa.NSFont;
36 import dwt.internal.cocoa.NSGraphicsContext;
29 import dwt.internal.cocoa.NSIndexSet; 37 import dwt.internal.cocoa.NSIndexSet;
30 import dwt.internal.cocoa.NSMutableIndexSet; 38 import dwt.internal.cocoa.NSMutableIndexSet;
39 import dwt.internal.cocoa.NSNotification;
31 import dwt.internal.cocoa.NSNumber; 40 import dwt.internal.cocoa.NSNumber;
32 import dwt.internal.cocoa.NSPoint; 41 import dwt.internal.cocoa.NSPoint;
33 import dwt.internal.cocoa.NSRange; 42 import dwt.internal.cocoa.NSRange;
34 import dwt.internal.cocoa.NSRect; 43 import dwt.internal.cocoa.NSRect;
44 import dwt.internal.cocoa.NSScrollView;
45 import dwt.internal.cocoa.NSSize;
35 import dwt.internal.cocoa.NSString; 46 import dwt.internal.cocoa.NSString;
36 import dwt.internal.cocoa.NSTableColumn; 47 import dwt.internal.cocoa.NSTableColumn;
48 import dwt.internal.cocoa.NSTableHeaderCell;
37 import dwt.internal.cocoa.NSTableHeaderView; 49 import dwt.internal.cocoa.NSTableHeaderView;
38 import dwt.internal.cocoa.NSTableView; 50 import dwt.internal.cocoa.NSTableView;
51 import dwt.internal.cocoa.NSView;
39 import dwt.internal.cocoa.OS; 52 import dwt.internal.cocoa.OS;
53 import dwt.internal.cocoa.SWTBrowserCell;
40 import dwt.internal.cocoa.SWTScrollView; 54 import dwt.internal.cocoa.SWTScrollView;
55 import dwt.internal.cocoa.SWTTableHeaderCell;
56 import dwt.internal.cocoa.SWTTableHeaderView;
41 import dwt.internal.cocoa.SWTTableView; 57 import dwt.internal.cocoa.SWTTableView;
58 import dwt.internal.cocoa.id;
42 59
43 /** 60 /**
44 * Instances of this class implement a selectable user interface 61 * Instances of this class implement a selectable user interface
45 * object that displays a list of images and strings and issues 62 * object that displays a list of images and strings and issues
46 * notification when selected. 63 * notification when selected.
67 * } 84 * }
68 * }); 85 * });
69 * </pre></code> 86 * </pre></code>
70 * </p><p> 87 * </p><p>
71 * Note that although this class is a subclass of <code>Composite</code>, 88 * Note that although this class is a subclass of <code>Composite</code>,
72 * it does not make sense to add <code>Control</code> children to it, 89 * it does not normally make sense to add <code>Control</code> children to
73 * or set a layout on it. 90 * it, or set a layout on it, unless implementing something like a cell
91 * editor.
74 * </p><p> 92 * </p><p>
75 * <dl> 93 * <dl>
76 * <dt><b>Styles:</b></dt> 94 * <dt><b>Styles:</b></dt>
77 * <dd>SINGLE, MULTI, CHECK, FULL_SELECTION, HIDE_SELECTION, VIRTUAL</dd> 95 * <dd>SINGLE, MULTI, CHECK, FULL_SELECTION, HIDE_SELECTION, VIRTUAL, NO_SCROLL</dd>
78 * <dt><b>Events:</b></dt> 96 * <dt><b>Events:</b></dt>
79 * <dd>Selection, DefaultSelection, SetData, MeasureItem, EraseItem, PaintItem</dd> 97 * <dd>Selection, DefaultSelection, SetData, MeasureItem, EraseItem, PaintItem</dd>
80 * </dl> 98 * </dl>
81 * </p><p> 99 * </p><p>
82 * Note: Only one of the styles SINGLE, and MULTI may be specified. 100 * Note: Only one of the styles SINGLE, and MULTI may be specified.
83 * </p><p> 101 * </p><p>
84 * IMPORTANT: This class is <em>not</em> intended to be subclassed. 102 * IMPORTANT: This class is <em>not</em> intended to be subclassed.
85 * </p> 103 * </p>
104 *
105 * @see <a href="http://www.eclipse.org/swt/snippets/#table">Table, TableItem, TableColumn snippets</a>
106 * @see <a href="http://www.eclipse.org/swt/examples.php">DWT Example: ControlExample</a>
107 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
86 */ 108 */
87 public class Table : Composite { 109 public class Table : Composite {
88 TableItem [] items; 110 TableItem [] items;
89 TableColumn [] columns; 111 TableColumn [] columns;
90 TableColumn sortColumn; 112 TableColumn sortColumn;
91 TableItem currentItem; 113 TableItem currentItem;
92 NSTableHeaderView headerView; 114 NSTableHeaderView headerView;
93 NSTableColumn firstColumn, checkColumn; 115 NSTableColumn firstColumn, checkColumn;
116 NSBrowserCell dataCell;
94 int columnCount, itemCount, lastIndexOf, sortDirection; 117 int columnCount, itemCount, lastIndexOf, sortDirection;
95 bool ignoreSelect; 118 bool ignoreSelect;
96 119
97 /** 120 /**
98 * Constructs a new instance of this class given its parent 121 * Constructs a new instance of this class given its parent
122 * @see DWT#MULTI 145 * @see DWT#MULTI
123 * @see DWT#CHECK 146 * @see DWT#CHECK
124 * @see DWT#FULL_SELECTION 147 * @see DWT#FULL_SELECTION
125 * @see DWT#HIDE_SELECTION 148 * @see DWT#HIDE_SELECTION
126 * @see DWT#VIRTUAL 149 * @see DWT#VIRTUAL
150 * @see DWT#NO_SCROLL
127 * @see Widget#checkSubclass 151 * @see Widget#checkSubclass
128 * @see Widget#getStyle 152 * @see Widget#getStyle
129 */ 153 */
130 public this (Composite parent, int style) { 154 public this (Composite parent, int style) {
131 super (parent, checkStyle (style)); 155 super (parent, checkStyle (style));
156 }
157
158 int accessibilityAttributeValue (int /*long*/ id, int /*long*/ sel, int /*long*/ arg0) {
159
160 if (accessible !is null) {
161 NSString attribute = new NSString(arg0);
162 id returnValue = accessible.internal_accessibilityAttributeValue(attribute, ACC.CHILDID_SELF);
163 if (returnValue !is null) return returnValue.id;
164 }
165
166 NSString attributeName = new NSString(arg0);
167
168 // Accessibility Verifier queries for a title or description. NSTableView doesn't
169 // seem to return either, so we return a default description value here.
170 if (attributeName.isEqualToString (OS.NSAccessibilityDescriptionAttribute)) {
171 return NSString.stringWith("").id;
172 }
173
174 return super.accessibilityAttributeValue(id, sel, arg0);
132 } 175 }
133 176
134 /** 177 /**
135 * Adds the listener to the collection of listeners who will 178 * Adds the listener to the collection of listeners who will
136 * be notified when the user changes the receiver's selection, by sending 179 * be notified when the user changes the receiver's selection, by sending
231 * @see DWT#SetData 274 * @see DWT#SetData
232 * 275 *
233 * @since 3.0 276 * @since 3.0
234 */ 277 */
235 public void clear (int index) { 278 public void clear (int index) {
236 checkWidget(); 279 checkWidget ();
237 if (!(0 <= index && index < itemCount)) error (DWT.ERROR_INVALID_RANGE); 280 if (!(0 <= index && index < itemCount)) error (DWT.ERROR_INVALID_RANGE);
238 TableItem item = items [index]; 281 TableItem item = items [index];
239 if (item !is null) { 282 if (item !is null) {
240 if (currentItem !is item) item.clear (); 283 item.clear ();
241 if (currentItem is null && drawCount is 0) { 284 NSTableView widget = (NSTableView) view;
242 int [] id = new int [] {index + 1}; 285 widget.reloadData ();
243 // OS.UpdateDataBrowserItems (handle, 0, id.length, id, OS.kDataBrowserItemNoProperty, OS.kDataBrowserNoItem); 286 }
244 } 287 }
245 // setScrollWidth (item);
246 }
247 }
248
249 /** 288 /**
250 * Removes the items from the receiver which are between the given 289 * Removes the items from the receiver which are between the given
251 * zero-relative start and end indices (inclusive). The text, icon 290 * zero-relative start and end indices (inclusive). The text, icon
252 * and other attributes of the items are set to their default values. 291 * and other attributes of the items are set to their default values.
253 * If the table was created with the <code>DWT.VIRTUAL</code> style, 292 * If the table was created with the <code>DWT.VIRTUAL</code> style,
268 * @see DWT#SetData 307 * @see DWT#SetData
269 * 308 *
270 * @since 3.0 309 * @since 3.0
271 */ 310 */
272 public void clear (int start, int end) { 311 public void clear (int start, int end) {
273 checkWidget(); 312 checkWidget ();
274 if (start > end) return; 313 if (start > end) return;
275 if (!(0 <= start && start <= end && end < itemCount)) { 314 if (!(0 <= start && start <= end && end < itemCount)) {
276 error (DWT.ERROR_INVALID_RANGE); 315 error (DWT.ERROR_INVALID_RANGE);
277 } 316 }
278 if (start is 0 && end is itemCount - 1) { 317 if (start is 0 && end is itemCount - 1) {
279 clearAll (); 318 clearAll ();
280 } else { 319 } else {
281 for (int i=start; i<=end; i++) { 320 for (int i=start; i<=end; i++) {
282 clear (i); 321 TableItem item = items [i];
283 } 322 if (item !is null) item.clear ();
323 }
324 NSTableView widget = (NSTableView) view;
325 widget.reloadData ();
284 } 326 }
285 } 327 }
286 328
287 /** 329 /**
288 * Clears the items at the given zero-relative indices in the receiver. 330 * Clears the items at the given zero-relative indices in the receiver.
305 * @see DWT#SetData 347 * @see DWT#SetData
306 * 348 *
307 * @since 3.0 349 * @since 3.0
308 */ 350 */
309 public void clear (int [] indices) { 351 public void clear (int [] indices) {
310 checkWidget(); 352 checkWidget ();
311 if (indices is null) error (DWT.ERROR_NULL_ARGUMENT); 353 if (indices is null) error (DWT.ERROR_NULL_ARGUMENT);
312 if (indices.length is 0) return; 354 if (indices.length is 0) return;
313 for (int i=0; i<indices.length; i++) { 355 for (int i=0; i<indices.length; i++) {
314 if (!(0 <= indices [i] && indices [i] < itemCount)) { 356 if (!(0 <= indices [i] && indices [i] < itemCount)) {
315 error (DWT.ERROR_INVALID_RANGE); 357 error (DWT.ERROR_INVALID_RANGE);
316 } 358 }
317 } 359 }
318 for (int i=0; i<indices.length; i++) { 360 for (int i=0; i<indices.length; i++) {
319 clear (indices [i]); 361 TableItem item = items [indices [i]];
320 } 362 if (item !is null) item.clear ();
363 }
364 NSTableView widget = (NSTableView) view;
365 widget.reloadData ();
321 } 366 }
322 367
323 /** 368 /**
324 * Clears all the items in the receiver. The text, icon and other 369 * Clears all the items in the receiver. The text, icon and other
325 * attributes of the items are set to their default values. If the 370 * attributes of the items are set to their default values. If the
335 * @see DWT#SetData 380 * @see DWT#SetData
336 * 381 *
337 * @since 3.0 382 * @since 3.0
338 */ 383 */
339 public void clearAll () { 384 public void clearAll () {
340 checkWidget(); 385 checkWidget ();
341 for (int i=0; i<itemCount; i++) { 386 for (int i=0; i<itemCount; i++) {
342 TableItem item = items [i]; 387 TableItem item = items [i];
343 if (item !is null) item.clear (); 388 if (item !is null) item.clear ();
344 } 389 }
345 if (currentItem is null && drawCount is 0) { 390 NSTableView widget = (NSTableView) view;
346 // OS.UpdateDataBrowserItems (handle, 0, 0, null, OS.kDataBrowserItemNoProperty, OS.kDataBrowserNoItem); 391 widget.reloadData ();
347 }
348 // setScrollWidth (items, true);
349 } 392 }
350 393
351 public Point computeSize (int wHint, int hHint, bool changed) { 394 public Point computeSize (int wHint, int hHint, bool changed) {
352 checkWidget(); 395 checkWidget ();
353 int width = 0; 396 int width = 0;
354 if (wHint is DWT.DEFAULT) { 397 if (wHint is DWT.DEFAULT) {
355 if (columnCount !is 0) { 398 if (columnCount !is 0) {
356 for (int i=0; i<columnCount; i++) { 399 for (int i=0; i<columnCount; i++) {
357 width += columns [i].getWidth (); 400 width += columns [i].getWidth ();
360 int columnWidth = 0; 403 int columnWidth = 0;
361 GC gc = new GC (this); 404 GC gc = new GC (this);
362 for (int i=0; i<itemCount; i++) { 405 for (int i=0; i<itemCount; i++) {
363 TableItem item = items [i]; 406 TableItem item = items [i];
364 if (item !is null) { 407 if (item !is null) {
365 columnWidth = Math.max (columnWidth, item.calculateWidth (0, gc)); 408 columnWidth = Math.max (columnWidth, item.calculateWidth (0, gc, false));
366 } 409 }
367 } 410 }
368 gc.dispose (); 411 gc.dispose ();
369 width += columnWidth + getInsetWidth (); 412 width += columnWidth + getInsetWidth ();
370 } 413 }
383 Rectangle rect = computeTrim (0, 0, width, height); 426 Rectangle rect = computeTrim (0, 0, width, height);
384 return new Point (rect.width, rect.height); 427 return new Point (rect.width, rect.height);
385 } 428 }
386 429
387 void createHandle () { 430 void createHandle () {
388 //TODO - DWT.CHECK 431 NSScrollView scrollWidget = (NSScrollView)new SWTScrollView().alloc();
389 SWTScrollView scrollWidget = cast(SWTScrollView)new SWTScrollView().alloc();
390 scrollWidget.initWithFrame(new NSRect ()); 432 scrollWidget.initWithFrame(new NSRect ());
391 scrollWidget.setHasHorizontalScroller(true); 433 scrollWidget.setHasHorizontalScroller(true);
392 scrollWidget.setHasVerticalScroller(true); 434 scrollWidget.setHasVerticalScroller(true);
393 scrollWidget.setAutohidesScrollers(true); 435 scrollWidget.setAutohidesScrollers(true);
394 scrollWidget.setBorderType(hasBorder() ? OS.NSBezelBorder : OS.NSNoBorder); 436 scrollWidget.setBorderType(hasBorder() ? OS.NSBezelBorder : OS.NSNoBorder);
395 scrollWidget.setTag(jniRef);
396 437
397 NSTableView widget = cast(NSTableView)new SWTTableView().alloc(); 438 NSTableView widget = cast(NSTableView)new SWTTableView().alloc();
398 widget.initWithFrame(new NSRect()); 439 widget.initWithFrame(new NSRect());
399 widget.setAllowsMultipleSelection((style & DWT.MULTI) !is 0); 440 widget.setAllowsMultipleSelection((style & DWT.MULTI) !is 0);
441 widget.setAllowsColumnReordering (false);
400 widget.setDataSource(widget); 442 widget.setDataSource(widget);
401 widget.setDelegate(widget); 443 widget.setDelegate(widget);
402 widget.setDoubleAction(OS.sel_sendDoubleSelection); 444 widget.setDoubleAction(OS.sel_sendDoubleSelection);
403 if (!hasBorder()) widget.setFocusRingType(OS.NSFocusRingTypeNone); 445 if (!hasBorder()) widget.setFocusRingType(OS.NSFocusRingTypeNone);
404 widget.setTag(jniRef); 446
405 447 headerView = (NSTableHeaderView)new SWTTableHeaderView ().alloc ().init ();
406 headerView = widget.headerView(); 448 widget.setHeaderView (null);
407 headerView.retain(); 449
408 widget.setHeaderView(null);
409
410 NSString str = NSString.stringWith(""); 450 NSString str = NSString.stringWith("");
411 if ((style & DWT.CHECK) !is 0) { 451 if ((style & DWT.CHECK) !is 0) {
412 checkColumn = cast(NSTableColumn)new NSTableColumn().alloc(); 452 checkColumn = cast(NSTableColumn)new NSTableColumn().alloc();
413 checkColumn.initWithIdentifier(str); 453 checkColumn.initWithIdentifier(checkColumn);
414 checkColumn.headerCell().setTitle(str); 454 checkColumn.headerCell().setTitle(str);
415 widget.addTableColumn (checkColumn); 455 widget.addTableColumn (checkColumn);
416 NSButtonCell cell = cast(NSButtonCell)new NSButtonCell().alloc().init(); 456 NSButtonCell cell = cast(NSButtonCell)new NSButtonCell().alloc().init();
417 checkColumn.setDataCell(cell); 457 checkColumn.setDataCell(cell);
418 cell.setButtonType(OS.NSSwitchButton); 458 cell.setButtonType(OS.NSSwitchButton);
423 checkColumn.setResizingMask(OS.NSTableColumnNoResizing); 463 checkColumn.setResizingMask(OS.NSTableColumnNoResizing);
424 checkColumn.setEditable(false); 464 checkColumn.setEditable(false);
425 } 465 }
426 466
427 firstColumn = cast(NSTableColumn)new NSTableColumn().alloc(); 467 firstColumn = cast(NSTableColumn)new NSTableColumn().alloc();
428 firstColumn.initWithIdentifier(str); 468 firstColumn.initWithIdentifier(firstColumn);
469 firstColumn.setMinWidth(0);
429 //column.setResizingMask(OS.NSTableColumnAutoresizingMask); 470 //column.setResizingMask(OS.NSTableColumnAutoresizingMask);
430 NSCell cell = cast(NSBrowserCell)new NSBrowserCell().alloc().init(); 471 dataCell = cast(NSBrowserCell)(new SWTBrowserCell ()).alloc ().init ();
431 firstColumn.setDataCell(cell); 472 firstColumn.setDataCell (dataCell);
432 cell.release();
433 widget.addTableColumn (firstColumn); 473 widget.addTableColumn (firstColumn);
434 474
435 scrollView = scrollWidget; 475 scrollView = scrollWidget;
436 view = widget; 476 view = widget;
437 scrollView.setDocumentView(widget);
438 parent.contentView().addSubview_(scrollView);
439 } 477 }
440 478
441 void createItem (TableColumn column, int index) { 479 void createItem (TableColumn column, int index) {
442 if (!(0 <= index && index <= columnCount)) error (DWT.ERROR_INVALID_RANGE); 480 if (!(0 <= index && index <= columnCount)) error (DWT.ERROR_INVALID_RANGE);
443 if (columnCount is columns.length) { 481 if (columnCount is columns.length) {
447 } 485 }
448 NSTableColumn nsColumn; 486 NSTableColumn nsColumn;
449 if (columnCount is 0) { 487 if (columnCount is 0) {
450 //TODO - clear attributes, alignment etc. 488 //TODO - clear attributes, alignment etc.
451 nsColumn = firstColumn; 489 nsColumn = firstColumn;
490 nsColumn.retain();
452 firstColumn = null; 491 firstColumn = null;
453 } else { 492 } else {
454 //TODO - set attributes, alignment etc. 493 //TODO - set attributes, alignment etc.
455 nsColumn = cast(NSTableColumn)new NSTableColumn().alloc(); 494 nsColumn = cast(NSTableColumn)new NSTableColumn().alloc();
456 nsColumn.initWithIdentifier(NSString.stringWith("")); 495 nsColumn.initWithIdentifier(nsColumn);
457 (cast(NSTableView)view).addTableColumn (nsColumn); 496 nsColumn.setMinWidth(0);
458 int checkColumn = (style & DWT.CHECK) !is 0 ? 1 : 0; 497 int checkColumn = (style & DWT.CHECK) !is 0 ? 1 : 0;
459 (cast(NSTableView)view).moveColumn (columnCount + checkColumn, index + checkColumn); 498 (cast(NSTableView)view).moveColumn (columnCount + checkColumn, index + checkColumn);
460 NSCell cell = cast(NSBrowserCell)new NSBrowserCell().alloc().init(); 499 nsColumn.setDataCell (dataCell);
461 nsColumn.setDataCell(cell); 500 }
462 cell.release(); 501 column.createJNIRef ();
463 } 502 NSTableHeaderCell headerCell = (NSTableHeaderCell)new SWTTableHeaderCell ().alloc ().init ();
503 nsColumn.setHeaderCell (headerCell);
504 display.addWidget (headerCell, column);
464 column.nsColumn = nsColumn; 505 column.nsColumn = nsColumn;
465 nsColumn.headerCell().setTitle(NSString.stringWith(""));
466 nsColumn.setWidth(0); 506 nsColumn.setWidth(0);
467 System.arraycopy (columns, index, columns, index + 1, columnCount++ - index); 507 System.arraycopy (columns, index, columns, index + 1, columnCount++ - index);
468 columns [index] = column; 508 columns [index] = column;
469 if (columnCount > 1) { 509 if (columnCount > 1) {
470 for (int i=0; i<itemCount; i++) { 510 for (int i=0; i<itemCount; i++) {
508 System.arraycopy (cellFont, index, temp, index+1, columnCount-index-1); 548 System.arraycopy (cellFont, index, temp, index+1, columnCount-index-1);
509 item.cellFont = temp; 549 item.cellFont = temp;
510 } 550 }
511 } 551 }
512 } 552 }
553 } else {
554 for (int i = 0; i < itemCount; i++) {
555 items [i].customWidth = -1;
556 }
513 } 557 }
514 } 558 }
515 559
516 void createItem (TableItem item, int index) { 560 void createItem (TableItem item, int index) {
517 if (!(0 <= index && index <= itemCount)) error (DWT.ERROR_INVALID_RANGE); 561 if (!(0 <= index && index <= itemCount)) error (DWT.ERROR_INVALID_RANGE);
540 584
541 Color defaultForeground () { 585 Color defaultForeground () {
542 return display.getSystemColor (DWT.COLOR_LIST_FOREGROUND); 586 return display.getSystemColor (DWT.COLOR_LIST_FOREGROUND);
543 } 587 }
544 588
589 void deregister () {
590 super.deregister ();
591 display.removeWidget (headerView);
592 display.removeWidget (dataCell);
593 }
594
545 /** 595 /**
546 * Deselects the item at the given zero-relative index in the receiver. 596 * Deselects the item at the given zero-relative index in the receiver.
547 * If the item at the index was already deselected, it remains 597 * If the item at the index was already deselected, it remains
548 * deselected. Indices that are out of range are ignored. 598 * deselected. Indices that are out of range are ignored.
549 * 599 *
553 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 603 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
554 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 604 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
555 * </ul> 605 * </ul>
556 */ 606 */
557 public void deselect (int index) { 607 public void deselect (int index) {
558 checkWidget(); 608 checkWidget ();
559 if (0 <= index && index < itemCount) { 609 if (0 <= index && index < itemCount) {
560 NSTableView widget = cast(NSTableView)view; 610 NSTableView widget = cast(NSTableView)view;
561 ignoreSelect = true; 611 ignoreSelect = true;
562 widget.deselectRow (index); 612 widget.deselectRow (index);
563 ignoreSelect = false; 613 ignoreSelect = false;
579 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 629 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
580 * </ul> 630 * </ul>
581 */ 631 */
582 public void deselect (int start, int end) { 632 public void deselect (int start, int end) {
583 checkWidget(); 633 checkWidget();
584 //TODO - check range 634 if (start > end) return;
635 if (end < 0 || start >= itemCount) return;
636 start = Math.max (0, start);
637 end = Math.min (itemCount - 1, end);
585 if (start is 0 && end is itemCount - 1) { 638 if (start is 0 && end is itemCount - 1) {
586 deselectAll (); 639 deselectAll ();
587 } else { 640 } else {
588 int length = end - start + 1;
589 NSTableView widget = cast(NSTableView)view; 641 NSTableView widget = cast(NSTableView)view;
590 ignoreSelect = true; 642 ignoreSelect = true;
591 for (int i=0; i<length; i++) { 643 for (int i=start; i<=end; i++) {
592 widget.deselectRow (i); 644 widget.deselectRow (i);
593 } 645 }
594 ignoreSelect = false; 646 ignoreSelect = false;
595 } 647 }
596 } 648 }
611 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 663 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
612 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 664 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
613 * </ul> 665 * </ul>
614 */ 666 */
615 public void deselect (int [] indices) { 667 public void deselect (int [] indices) {
616 checkWidget(); 668 checkWidget ();
617 if (indices is null) error (DWT.ERROR_NULL_ARGUMENT); 669 if (indices is null) error (DWT.ERROR_NULL_ARGUMENT);
618 NSTableView widget = cast(NSTableView)view; 670 NSTableView widget = cast(NSTableView)view;
619 ignoreSelect = true; 671 ignoreSelect = true;
620 for (int i=0; i<indices.length; i++) { 672 for (int i=0; i<indices.length; i++) {
621 widget.deselectRow (indices [i]); 673 widget.deselectRow (indices [i]);
699 item.cellFont = temp; 751 item.cellFont = temp;
700 } 752 }
701 } 753 }
702 } 754 }
703 } 755 }
756
757 int oldIndex = (int)/*64*/((NSTableView)view).columnWithIdentifier (column.nsColumn);
758
704 if (columnCount is 1) { 759 if (columnCount is 1) {
705 //TODO - reset attributes 760 //TODO - reset attributes
706 firstColumn = column.nsColumn; 761 firstColumn = column.nsColumn;
707 firstColumn.setWidth (0); 762 firstColumn.setWidth (0);
708 } else { 763 } else {
709 (cast(NSTableView)view).removeTableColumn(column.nsColumn); 764 (cast(NSTableView)view).removeTableColumn(column.nsColumn);
710 } 765 }
711 System.arraycopy (columns, index + 1, columns, index, --columnCount - index); 766 System.arraycopy (columns, index + 1, columns, index, --columnCount - index);
712 columns [columnCount] = null; 767 columns [columnCount] = null;
713 for (int i=index; i<columnCount; i++) { 768
714 columns [i].sendEvent (DWT.Move); 769 NSArray array = ((NSTableView)view).tableColumns ();
770 int arraySize = (int)/*64*/array.count ();
771 for (int i = oldIndex; i < arraySize; i++) {
772 int /*long*/ columnId = array.objectAtIndex (i).id;
773 for (int j = 0; j < columnCount; j++) {
774 if (columns[j].nsColumn.id is columnId) {
775 columns [j].sendEvent (DWT.Move);
776 break;
777 }
778 }
715 } 779 }
716 } 780 }
717 781
718 void destroyItem (TableItem item) { 782 void destroyItem (TableItem item) {
719 int index = 0; 783 int index = 0;
727 (cast(NSTableView)view).noteNumberOfRowsChanged(); 791 (cast(NSTableView)view).noteNumberOfRowsChanged();
728 if (itemCount is 0) { 792 if (itemCount is 0) {
729 setTableEmpty (); 793 setTableEmpty ();
730 } else { 794 } else {
731 // fixScrollBar (); 795 // fixScrollBar ();
796 }
797 }
798
799 void drawInteriorWithFrame_inView (int /*long*/ id, int /*long*/ sel, int /*long*/ cellFrame, int /*long*/ view) {
800 NSRect rect = new NSRect ();
801 OS.memmove (rect, cellFrame, NSRect.sizeof);
802
803 NSTableView tableView = (NSTableView)this.view;
804 NSBrowserCell cell = new NSBrowserCell (id);
805 NSRange rowsRange = tableView.rowsInRect (rect);
806 int rowIndex = (int)/*64*/rowsRange.location;
807 TableItem item = items [rowIndex];
808 int columnIndex = 0;
809 int nsColumnIndex = 0;
810 if (columnCount !is 0) {
811 NSIndexSet columnsSet = tableView.columnIndexesInRect (rect);
812 nsColumnIndex = (int)/*64*/columnsSet.firstIndex ();
813 NSArray nsColumns = tableView.tableColumns ();
814 id nsColumn = nsColumns.objectAtIndex (nsColumnIndex);
815 for (int i = 0; i < columnCount; i++) {
816 if (columns[i].nsColumn.id is nsColumn.id) {
817 columnIndex = indexOf (columns[i]);
818 break;
819 }
820 }
821 }
822
823 Color background = item.cellBackground !is null ? item.cellBackground [columnIndex] : null;
824 if (background is null) background = item.background;
825 bool drawBackground = background !is null;
826 bool drawForeground = true;
827 bool isSelected = tableView.isRowSelected (rowIndex);
828 bool drawSelection = isSelected;
829
830 NSColor nsSelectionBackground = null;
831 NSColor nsSelectionForeground = null;
832 if (isSelected) {
833 if (isFocusControl ()) {
834 nsSelectionForeground = NSColor.alternateSelectedControlTextColor ();
835 } else {
836 nsSelectionForeground = NSColor.selectedControlTextColor ();
837 }
838 nsSelectionForeground = nsSelectionForeground.colorUsingColorSpace (NSColorSpace.deviceRGBColorSpace ());
839 nsSelectionBackground = cell.highlightColorInView (tableView);
840 nsSelectionBackground = nsSelectionBackground.colorUsingColorSpace (NSColorSpace.deviceRGBColorSpace ());
841 }
842
843 NSRect fullRect = new NSRect ();
844 fullRect.x = rect.x; fullRect.y = rect.y; fullRect.height = rect.height;
845 if (columnCount is 0) {
846 if (item.customWidth !is -1) {
847 fullRect.width = item.customWidth;
848 } else {
849 NSSize contentSize = cell.cellSizeForBounds (rect);
850 fullRect.width = contentSize.width;
851 }
852 } else {
853 NSSize spacing = tableView.intercellSpacing ();
854 fullRect.width = rect.width + spacing.width;
855 }
856
857 if (hooks (DWT.EraseItem)) {
858 NSRect eraseItemRect = null;
859 // TODO how to handle rearranged columns? The third clause below ensures that
860 // there are either 0 columns or that column 0 is still the first physical column.
861 if (columnIndex is 0 && (style & DWT.CHECK) !is 0 && (columnCount is 0 || tableView.columnWithIdentifier (columns[0].nsColumn) is 1)) {
862 eraseItemRect = new NSRect ();
863 eraseItemRect.y = fullRect.y;
864 eraseItemRect.width = fullRect.x + fullRect.width;
865 eraseItemRect.height = fullRect.height;
866 } else {
867 eraseItemRect = fullRect;
868 }
869 GCData data = new GCData ();
870 data.paintRect = eraseItemRect;
871 GC gc = GC.cocoa_new (this, data);
872 gc.setFont (item.getFont (columnIndex));
873 if (isSelected) {
874 float /*double*/[] components = new float /*double*/[(int)/*64*/nsSelectionForeground.numberOfComponents ()];
875 nsSelectionForeground.getComponents (components);
876 Color selectionForeground = Color.cocoa_new (display, components);
877 gc.setForeground (selectionForeground);
878 components = new float /*double*/[(int)/*64*/nsSelectionBackground.numberOfComponents ()];
879 nsSelectionBackground.getComponents (components);
880 Color selectionBackground = Color.cocoa_new (display, components);
881 gc.setBackground (selectionBackground);
882 } else {
883 gc.setForeground (item.getForeground (columnIndex));
884 gc.setBackground (item.getBackground (columnIndex));
885 }
886
887 Event event = new Event ();
888 event.item = item;
889 event.gc = gc;
890 event.index = columnIndex;
891 event.detail = DWT.FOREGROUND;
892 if (drawBackground) event.detail |= DWT.BACKGROUND;
893 if (isSelected) event.detail |= DWT.SELECTED;
894 event.x = (int)eraseItemRect.x;
895 event.y = (int)eraseItemRect.y;
896 event.width = (int)eraseItemRect.width;
897 event.height = (int)eraseItemRect.height;
898 sendEvent (DWT.EraseItem, event);
899 gc.dispose ();
900 if (item.isDisposed ()) return;
901 if (!event.doit) {
902 drawForeground = drawBackground = drawSelection = false;
903 } else {
904 drawBackground = drawBackground && (event.detail & DWT.BACKGROUND) !is 0;
905 drawForeground = (event.detail & DWT.FOREGROUND) !is 0;
906 drawSelection = drawSelection && (event.detail & DWT.SELECTED) !is 0;
907 }
908
909 if (drawSelection) {
910 NSRect selectionRect = new NSRect ();
911 selectionRect.y = rect.y; selectionRect.height = rect.height;
912 if (columnCount > 0) {
913 NSRect columnRect = tableView.rectOfColumn (nsColumnIndex);
914 selectionRect.x = columnRect.x; selectionRect.width = columnRect.width;
915 } else {
916 NSRect rowRect = tableView.rectOfRow (rowIndex);
917 if ((style & DWT.CHECK) !is 0) {
918 /* highlighting at this stage draws over the checkbox, so don't include its column */
919 int checkWidth = (int)/*64*/checkColumn.width ();
920 selectionRect.x = checkWidth;
921 selectionRect.width = rowRect.width - checkWidth;
922 } else {
923 selectionRect.width = rowRect.width;
924 }
925 }
926 callSuper (tableView.id, OS.sel_highlightSelectionInClipRect_, selectionRect);
927 }
928 }
929
930 if (drawBackground && !drawSelection) {
931 NSGraphicsContext context = NSGraphicsContext.currentContext ();
932 context.saveGraphicsState ();
933 float[] colorRGB = background.handle;
934 NSColor color = NSColor.colorWithDeviceRed (colorRGB[0], colorRGB[1], colorRGB[2], 1f);
935 color.setFill ();
936 NSBezierPath.fillRect (fullRect);
937 context.restoreGraphicsState ();
938 }
939
940 if (drawForeground) {
941 cell.setHighlighted (false);
942 callSuper (id, sel, rect, view);
943 }
944
945 if (hooks (DWT.PaintItem)) {
946 NSRect contentRect = cell.titleRectForBounds (rect);
947 NSSize contentSize = cell.cellSizeForBounds (rect);
948
949 GCData data = new GCData ();
950 // TODO how to handle rearranged columns? The third clause below ensures that
951 // there are either 0 columns or that column 0 is still the first physical column.
952 if (columnIndex is 0 && (style & DWT.CHECK) !is 0 && (columnCount is 0 || tableView.columnWithIdentifier (columns[0].nsColumn) is 1)) {
953 NSRect gcRect = new NSRect ();
954 gcRect.y = fullRect.y;
955 gcRect.width = fullRect.x + fullRect.width;
956 gcRect.height = fullRect.height;
957 data.paintRect = gcRect;
958 } else {
959 data.paintRect = fullRect;
960 }
961 GC gc = GC.cocoa_new (this, data);
962 gc.setFont (item.getFont (columnIndex));
963 if (isSelected) {
964 float /*double*/[] components = new float /*double*/[(int)/*64*/nsSelectionForeground.numberOfComponents ()];
965 nsSelectionForeground.getComponents (components);
966 Color selectionForeground = Color.cocoa_new (display, components);
967 gc.setForeground (selectionForeground);
968 components = new float /*double*/[(int)/*64*/nsSelectionBackground.numberOfComponents ()];
969 nsSelectionBackground.getComponents (components);
970 Color selectionBackground = Color.cocoa_new (display, components);
971 gc.setBackground (selectionBackground);
972 gc.setBackground (display.getSystemColor (DWT.COLOR_GREEN));
973 } else {
974 gc.setForeground (item.getForeground (columnIndex));
975 gc.setBackground (item.getBackground (columnIndex));
976 }
977
978 Event event = new Event ();
979 event.item = item;
980 event.gc = gc;
981 event.index = columnIndex;
982 if (isSelected) event.detail |= DWT.SELECTED;
983 event.x = (int)contentRect.x;
984 event.y = (int)contentRect.y;
985 event.width = (int)Math.ceil (contentSize.width);
986 event.height = (int)Math.ceil (fullRect.height);
987 sendEvent (DWT.PaintItem, event);
988 gc.dispose ();
732 } 989 }
733 } 990 }
734 991
735 void fixSelection (int index, bool add) { 992 void fixSelection (int index, bool add) {
736 int [] selection = getSelectionIndices (); 993 int [] selection = getSelectionIndices ();
754 1011
755 int getCheckColumnWidth () { 1012 int getCheckColumnWidth () {
756 return 20; //TODO - compute width 1013 return 20; //TODO - compute width
757 } 1014 }
758 1015
1016 TableColumn getColumn (id id) {
1017 for (int i = 0; i < columnCount; i++) {
1018 if (columns[i].nsColumn.id is id.id) {
1019 return columns[i];
1020 }
1021 }
1022 return null;
1023 }
1024
759 /** 1025 /**
760 * Returns the column at the given, zero-relative index in the 1026 * Returns the column at the given, zero-relative index in the
761 * receiver. Throws an exception if the index is out of range. 1027 * receiver. Throws an exception if the index is out of range.
762 * Columns are returned in the order that they were created. 1028 * Columns are returned in the order that they were created.
763 * If no <code>TableColumn</code>s were created by the programmer, 1029 * If no <code>TableColumn</code>s were created by the programmer,
837 * @since 3.1 1103 * @since 3.1
838 */ 1104 */
839 public int [] getColumnOrder () { 1105 public int [] getColumnOrder () {
840 checkWidget (); 1106 checkWidget ();
841 int [] order = new int [columnCount]; 1107 int [] order = new int [columnCount];
842 int [] position = new int [1]; 1108 for (int i = 0; i < columnCount; i++) {
843 for (int i=0; i<columnCount; i++) {
844 TableColumn column = columns [i]; 1109 TableColumn column = columns [i];
845 // OS.GetDataBrowserTableViewColumnPosition (handle, column.id, position); 1110 int index = ((NSTableView)view).columnWithIdentifier (column.nsColumn);
846 // if ((style & DWT.CHECK) !is 0) position [0] -= 1; 1111 if ((style & DWT.CHECK) !is 0) index -= 1;
847 order [position [0]] = i; 1112 order [index] = i;
848 } 1113 }
849 return order; 1114 return order;
850 } 1115 }
851 1116
852 /** 1117 /**
988 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1253 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
989 * </ul> 1254 * </ul>
990 */ 1255 */
991 public TableItem getItem (Point point) { 1256 public TableItem getItem (Point point) {
992 checkWidget (); 1257 checkWidget ();
993 // checkItems (true); 1258 NSTableView widget = (NSTableView)view;
994 // if (point is null) error (DWT.ERROR_NULL_ARGUMENT); 1259 NSPoint pt = new NSPoint();
995 // Rect rect = new Rect (); 1260 pt.x = point.x;
996 // dwt.internal.carbon.Point pt = new dwt.internal.carbon.Point (); 1261 pt.y = point.y;
997 // OS.SetPt (pt, cast(short) point.x, cast(short) point.y); 1262 int row = cast(int)/*64*/widget.rowAtPoint(pt);
998 // if (0 < lastHittest && lastHittest <= itemCount && lastHittestColumn !is 0) { 1263 if (row is -1) return null;
999 // if (OS.GetDataBrowserItemPartBounds (handle, lastHittest, lastHittestColumn, OS.kDataBrowserPropertyEnclosingPart, rect) is OS.noErr) { 1264 return items[row];
1000 // if (rect.top <= pt.v && pt.v <= rect.bottom) {
1001 // if ((style & DWT.FULL_SELECTION) !is 0) {
1002 // return _getItem (lastHittest - 1);
1003 // } else {
1004 // return OS.PtInRect (pt, rect) ? _getItem (lastHittest - 1) : null;
1005 // }
1006 // }
1007 // }
1008 //
1009 // }
1010 // int [] top = new int [1], left = new int [1];
1011 // OS.GetDataBrowserScrollPosition(handle, top, left);
1012 // short [] height = new short [1];
1013 // OS.GetDataBrowserTableViewRowHeight (handle, height);
1014 // short [] header = new short [1];
1015 // OS.GetDataBrowserListViewHeaderBtnHeight (handle, header);
1016 // int [] offsets = new int [] {0, 1, -1};
1017 // for (int i = 0; i < offsets.length; i++) {
1018 // int index = (top[0] - header [0] + point.y) / height [0] + offsets [i];
1019 // if (0 <= index && index < itemCount) {
1020 // if (columnCount is 0) {
1021 // if (OS.GetDataBrowserItemPartBounds (handle, index + 1, column_id, OS.kDataBrowserPropertyEnclosingPart, rect) is OS.noErr) {
1022 // if (rect.top <= pt.v && pt.v <= rect.bottom) {
1023 // if ((style & DWT.FULL_SELECTION) !is 0) {
1024 // return _getItem (index);
1025 // } else {
1026 // return OS.PtInRect (pt, rect) ? _getItem (index) : null;
1027 // }
1028 // }
1029 // }
1030 // } else {
1031 // for (int j = 0; j < columnCount; j++) {
1032 // if (OS.GetDataBrowserItemPartBounds (handle, index + 1, columns [j].id, OS.kDataBrowserPropertyEnclosingPart, rect) is OS.noErr) {
1033 // if (rect.top <= pt.v && pt.v <= rect.bottom) {
1034 // if ((style & DWT.FULL_SELECTION) !is 0) {
1035 // return _getItem (index);
1036 // } else {
1037 // return OS.PtInRect (pt, rect) ? _getItem (index) : null;
1038 // }
1039 // }
1040 // }
1041 // }
1042 // }
1043 // }
1044 // }
1045 // //TODO - optimize
1046 // for (int i=0; i<itemCount; i++) {
1047 // if (columnCount is 0) {
1048 // if (OS.GetDataBrowserItemPartBounds (handle, i + 1, column_id, OS.kDataBrowserPropertyEnclosingPart, rect) is OS.noErr) {
1049 // if (rect.top <= pt.v && pt.v <= rect.bottom) {
1050 // if ((style & DWT.FULL_SELECTION) !is 0) {
1051 // return _getItem (i);
1052 // } else {
1053 // return OS.PtInRect (pt, rect) ? _getItem (i) : null;
1054 // }
1055 // }
1056 // }
1057 // } else {
1058 // for (int j = 0; j < columnCount; j++) {
1059 // if (OS.GetDataBrowserItemPartBounds (handle, i + 1, columns [j].id, OS.kDataBrowserPropertyEnclosingPart, rect) is OS.noErr) {
1060 // if (rect.top <= pt.v && pt.v <= rect.bottom) {
1061 // if ((style & DWT.FULL_SELECTION) !is 0) {
1062 // return _getItem (i);
1063 // } else {
1064 // return OS.PtInRect (pt, rect) ? _getItem (i) : null;
1065 // }
1066 // }
1067 // }
1068 // }
1069 // }
1070 // }
1071 return null;
1072 } 1265 }
1073 1266
1074 /** 1267 /**
1075 * Returns the number of items contained in the receiver. 1268 * Returns the number of items contained in the receiver.
1076 * 1269 *
1086 return itemCount; 1279 return itemCount;
1087 } 1280 }
1088 1281
1089 /** 1282 /**
1090 * Returns the height of the area which would be used to 1283 * Returns the height of the area which would be used to
1091 * display <em>one</em> of the items in the receiver's. 1284 * display <em>one</em> of the items in the receiver.
1092 * 1285 *
1093 * @return the height of one item 1286 * @return the height of one item
1094 * 1287 *
1095 * @exception DWTException <ul> 1288 * @exception DWTException <ul>
1096 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1289 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1148 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1341 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1149 * </ul> 1342 * </ul>
1150 */ 1343 */
1151 public bool getLinesVisible () { 1344 public bool getLinesVisible () {
1152 checkWidget (); 1345 checkWidget ();
1153 // if (OS.VERSION >= 0x1040) { 1346 return ((NSTableView)view).usesAlternatingRowBackgroundColors();
1154 // int [] attrib = new int [1];
1155 // OS.DataBrowserGetAttributes (handle, attrib);
1156 // return (attrib [0] & (OS.kDataBrowserAttributeListViewAlternatingRowColors | OS.kDataBrowserAttributeListViewDrawColumnDividers)) !is 0;
1157 // }
1158 return false;
1159 } 1347 }
1160 1348
1161 /** 1349 /**
1162 * Returns an array of <code>TableItem</code>s that are currently 1350 * Returns an array of <code>TableItem</code>s that are currently
1163 * selected in the receiver. The order of the items is unspecified. 1351 * selected in the receiver. The order of the items is unspecified.
1179 NSTableView widget = cast(NSTableView)view; 1367 NSTableView widget = cast(NSTableView)view;
1180 if (widget.numberOfSelectedRows() is 0) { 1368 if (widget.numberOfSelectedRows() is 0) {
1181 return new TableItem [0]; 1369 return new TableItem [0];
1182 } 1370 }
1183 NSIndexSet selection = widget.selectedRowIndexes(); 1371 NSIndexSet selection = widget.selectedRowIndexes();
1184 int count = selection.count(); 1372 int count = (int)/*64*/selection.count();
1185 int [] indexBuffer = new int [count]; 1373 int /*long*/ [] indexBuffer = new int /*long*/ [count];
1186 selection.getIndexes(indexBuffer, count, 0); 1374 selection.getIndexes(indexBuffer, count, 0);
1187 TableItem [] result = new TableItem [count]; 1375 TableItem [] result = new TableItem [count];
1188 for (int i=0; i<count; i++) { 1376 for (int i=0; i<count; i++) {
1189 result [i] = _getItem (indexBuffer [i]); 1377 result [i] = _getItem ((int)/*64*/indexBuffer [i]);
1190 } 1378 }
1191 return result; 1379 return result;
1192 } 1380 }
1193 1381
1194 /** 1382 /**
1201 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1389 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1202 * </ul> 1390 * </ul>
1203 */ 1391 */
1204 public int getSelectionCount () { 1392 public int getSelectionCount () {
1205 checkWidget (); 1393 checkWidget ();
1206 return (cast(NSTableView)view).numberOfSelectedRows(); 1394 return cast(int)/*64*/(cast(NSTableView)view).numberOfSelectedRows();
1207 } 1395 }
1208 1396
1209 /** 1397 /**
1210 * Returns the zero-relative index of the item which is currently 1398 * Returns the zero-relative index of the item which is currently
1211 * selected in the receiver, or -1 if no item is selected. 1399 * selected in the receiver, or -1 if no item is selected.
1216 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1404 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1217 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1405 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1218 * </ul> 1406 * </ul>
1219 */ 1407 */
1220 public int getSelectionIndex () { 1408 public int getSelectionIndex () {
1221 checkWidget(); 1409 checkWidget ();
1222 //TODO - check empty selection case 1410 NSTableView widget = (NSTableView)view;
1223 return (cast(NSTableView)view).selectedRow(); 1411 if (widget.numberOfSelectedRows() is 0) {
1412 return -1;
1413 }
1414 NSIndexSet selection = widget.selectedRowIndexes();
1415 int count = (int)/*64*/selection.count();
1416 int /*long*/ [] result = new int /*long*/ [count];
1417 selection.getIndexes(result, count, 0);
1418 return (int)/*64*/result [0];
1224 } 1419 }
1225 1420
1226 /** 1421 /**
1227 * Returns the zero-relative indices of the items which are currently 1422 * Returns the zero-relative indices of the items which are currently
1228 * selected in the receiver. The order of the indices is unspecified. 1423 * selected in the receiver. The order of the indices is unspecified.
1244 NSTableView widget = cast(NSTableView)view; 1439 NSTableView widget = cast(NSTableView)view;
1245 if (widget.numberOfSelectedRows() is 0) { 1440 if (widget.numberOfSelectedRows() is 0) {
1246 return new int [0]; 1441 return new int [0];
1247 } 1442 }
1248 NSIndexSet selection = widget.selectedRowIndexes(); 1443 NSIndexSet selection = widget.selectedRowIndexes();
1249 int count = selection.count(); 1444 int count = (int)/*64*/selection.count();
1445 int /*long*/ [] indices = new int /*long*/ [count];
1446 selection.getIndexes(indices, count, 0);
1250 int [] result = new int [count]; 1447 int [] result = new int [count];
1251 selection.getIndexes(result, count, 0); 1448 for (int i = 0; i < indices.length; i++) {
1449 result [i] = (int)/*64*/indices [i];
1450 }
1252 return result; 1451 return result;
1253 } 1452 }
1254 1453
1255 /** 1454 /**
1256 * Returns the column which shows the sort indicator for 1455 * Returns the column which shows the sort indicator for
1305 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1504 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1306 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1505 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1307 * </ul> 1506 * </ul>
1308 */ 1507 */
1309 public int getTopIndex () { 1508 public int getTopIndex () {
1310 checkWidget(); 1509 checkWidget ();
1311 //TODO - partial item at the top 1510 //TODO - partial item at the top
1312 NSRect rect = scrollView.documentVisibleRect(); 1511 NSRect rect = scrollView.documentVisibleRect();
1313 NSPoint point = new NSPoint(); 1512 NSPoint point = new NSPoint();
1314 point.x = rect.x; 1513 point.x = rect.x;
1315 point.y = rect.y; 1514 point.y = rect.y;
1316 return (cast(NSTableView)view).rowAtPoint(point); 1515 return csat(int)/*64*/(cast(NSTableView)view).rowAtPoint(point);
1317 } 1516 }
1318 1517
1518 void highlightSelectionInClipRect(int /*long*/ id, int /*long*/ sel, int /*long*/ rect) {
1519 if (!hooks (DWT.EraseItem)) {
1520 NSRect clipRect = new NSRect ();
1521 OS.memmove (clipRect, rect, NSRect.sizeof);
1522 callSuper (id, sel, clipRect);
1523 }
1524 }
1319 1525
1320 /** 1526 /**
1321 * Searches the receiver's list starting at the first column 1527 * Searches the receiver's list starting at the first column
1322 * (index 0) until a column is found that is equal to the 1528 * (index 0) until a column is found that is equal to the
1323 * argument, and returns the index of that column. If no column 1529 * argument, and returns the index of that column. If no column
1392 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1598 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1393 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1599 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1394 * </ul> 1600 * </ul>
1395 */ 1601 */
1396 public bool isSelected (int index) { 1602 public bool isSelected (int index) {
1397 checkWidget(); 1603 checkWidget ();
1398 //TODO - range check 1604 if (!(0 <= index && index < itemCount)) return false;
1399 return (cast(NSTableView)view).isRowSelected(index); 1605 return (cast(NSTableView)view).isRowSelected(index);
1400 } 1606 }
1401 1607
1402 int numberOfRowsInTableView(int aTableView) { 1608 bool isTrim (NSView view) {
1609 if (super.isTrim (view)) return true;
1610 return view.id is headerView.id;
1611 }
1612
1613 int /*long*/ numberOfRowsInTableView(int /*long*/ id, int /*long*/ sel, int /*long*/ aTableView) {
1403 return itemCount; 1614 return itemCount;
1615 }
1616
1617 void register () {
1618 super.register ();
1619 display.addWidget (headerView, this);
1620 display.addWidget (dataCell, this);
1404 } 1621 }
1405 1622
1406 void releaseChildren (bool destroy) { 1623 void releaseChildren (bool destroy) {
1407 if (items !is null) { 1624 if (items !is null) {
1408 for (int i=0; i<itemCount; i++) { 1625 for (int i=0; i<itemCount; i++) {
1431 headerView = null; 1648 headerView = null;
1432 if (firstColumn !is null) firstColumn.release(); 1649 if (firstColumn !is null) firstColumn.release();
1433 firstColumn = null; 1650 firstColumn = null;
1434 if (checkColumn !is null) checkColumn.release(); 1651 if (checkColumn !is null) checkColumn.release();
1435 checkColumn = null; 1652 checkColumn = null;
1653 if (dataCell !is null) dataCell.release();
1654 dataCell = null;
1436 } 1655 }
1437 1656
1438 void releaseWidget () { 1657 void releaseWidget () {
1439 super.releaseWidget (); 1658 super.releaseWidget ();
1440 currentItem = null; 1659 currentItem = null;
1454 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1673 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1455 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1674 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1456 * </ul> 1675 * </ul>
1457 */ 1676 */
1458 public void remove (int index) { 1677 public void remove (int index) {
1459 checkWidget(); 1678 checkWidget ();
1460 if (!(0 <= index && index < itemCount)) error (DWT.ERROR_INVALID_RANGE); 1679 if (!(0 <= index && index < itemCount)) error (DWT.ERROR_INVALID_RANGE);
1461 TableItem item = items [index]; 1680 TableItem item = items [index];
1462 if (item !is null) item.release (false); 1681 if (item !is null) item.release (false);
1463 if (index !is itemCount - 1) fixSelection (index, false); 1682 if (index !is itemCount - 1) fixSelection (index, false);
1464 System.arraycopy (items, index + 1, items, index, --itemCount - index); 1683 System.arraycopy (items, index + 1, items, index, --itemCount - index);
1486 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1705 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1487 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1706 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1488 * </ul> 1707 * </ul>
1489 */ 1708 */
1490 public void remove (int start, int end) { 1709 public void remove (int start, int end) {
1491 checkWidget(); 1710 checkWidget ();
1492 if (start > end) return; 1711 if (start > end) return;
1493 if (!(0 <= start && start <= end && end < itemCount)) { 1712 if (!(0 <= start && start <= end && end < itemCount)) {
1494 error (DWT.ERROR_INVALID_RANGE); 1713 error (DWT.ERROR_INVALID_RANGE);
1495 } 1714 }
1496 if (start is 0 && end is itemCount - 1) { 1715 if (start is 0 && end is itemCount - 1) {
1544 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1763 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1545 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1764 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1546 * </ul> 1765 * </ul>
1547 */ 1766 */
1548 public void removeAll () { 1767 public void removeAll () {
1549 checkWidget(); 1768 checkWidget ();
1550 for (int i=0; i<itemCount; i++) { 1769 for (int i=0; i<itemCount; i++) {
1551 TableItem item = items [i]; 1770 TableItem item = items [i];
1552 if (item !is null && !item.isDisposed ()) item.release (false); 1771 if (item !is null && !item.isDisposed ()) item.release (false);
1553 } 1772 }
1554 setTableEmpty (); 1773 setTableEmpty ();
1591 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 1810 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1592 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 1811 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1593 * </ul> 1812 * </ul>
1594 */ 1813 */
1595 public void select (int index) { 1814 public void select (int index) {
1596 checkWidget(); 1815 checkWidget ();
1597 if (0 <= index && index < itemCount) { 1816 if (0 <= index && index < itemCount) {
1598 NSIndexSet indexes = cast(NSIndexSet)new NSIndexSet().alloc(); 1817 NSIndexSet indexes = cast(NSIndexSet)new NSIndexSet().alloc();
1599 indexes.initWithIndex(index); 1818 indexes.initWithIndex(index);
1600 NSTableView widget = cast(NSTableView)view; 1819 NSTableView widget = cast(NSTableView)view;
1601 ignoreSelect = true; 1820 ignoreSelect = true;
1602 (cast(NSTableView)view).selectRowIndexes(indexes, true); 1821 widget.selectRowIndexes(indexes, (style & DWT.MULTI) !is 0);
1603 ignoreSelect = false; 1822 ignoreSelect = false;
1604 } 1823 }
1605 } 1824 }
1606 1825
1607 /** 1826 /**
1642 range.location = start; 1861 range.location = start;
1643 range.length = length; 1862 range.length = length;
1644 indexes.initWithIndexesInRange(range); 1863 indexes.initWithIndexesInRange(range);
1645 NSTableView widget = cast(NSTableView)view; 1864 NSTableView widget = cast(NSTableView)view;
1646 ignoreSelect = true; 1865 ignoreSelect = true;
1647 widget.selectRowIndexes(indexes, true); 1866 widget.selectRowIndexes(indexes, (style & DWT.MULTI) !is 0);
1648 ignoreSelect = false; 1867 ignoreSelect = false;
1649 } 1868 }
1650 } 1869 }
1651 1870
1652 /** 1871 /**
1678 int length = indices.length; 1897 int length = indices.length;
1679 if (length is 0 || ((style & DWT.SINGLE) !is 0 && length > 1)) return; 1898 if (length is 0 || ((style & DWT.SINGLE) !is 0 && length > 1)) return;
1680 int count = 0; 1899 int count = 0;
1681 NSMutableIndexSet indexes = cast(NSMutableIndexSet)new NSMutableIndexSet().alloc().init(); 1900 NSMutableIndexSet indexes = cast(NSMutableIndexSet)new NSMutableIndexSet().alloc().init();
1682 for (int i=0; i<length; i++) { 1901 for (int i=0; i<length; i++) {
1683 int index = indices [length - i - 1]; 1902 int index = indices [i];
1684 if (index >= 0 && index < itemCount) { 1903 if (index >= 0 && index < itemCount) {
1685 indexes.addIndex (indices [i]); 1904 indexes.addIndex (indices [i]);
1686 count++; 1905 count++;
1687 } 1906 }
1688 } 1907 }
1689 if (count > 0) { 1908 if (count > 0) {
1690 NSTableView widget = cast(NSTableView)view; 1909 NSTableView widget = cast(NSTableView)view;
1691 ignoreSelect = true; 1910 ignoreSelect = true;
1692 widget.selectRowIndexes(indexes, true); 1911 widget.selectRowIndexes(indexes, (style & DWT.MULTI) !is 0);
1693 ignoreSelect = false; 1912 ignoreSelect = false;
1694 } 1913 }
1695 } 1914 }
1696 1915
1697 void select (int [] ids, int count, bool clear) { 1916 void select (int [] ids, int count, bool clear) {
1719 if ((style & DWT.SINGLE) !is 0) return; 1938 if ((style & DWT.SINGLE) !is 0) return;
1720 NSTableView widget = cast(NSTableView)view; 1939 NSTableView widget = cast(NSTableView)view;
1721 ignoreSelect = true; 1940 ignoreSelect = true;
1722 widget.selectAll(null); 1941 widget.selectAll(null);
1723 ignoreSelect = false; 1942 ignoreSelect = false;
1943 }
1944
1945 void setBackground (float [] color) {
1946 super.setBackground (color);
1947 NSColor nsColor;
1948 if (color is null) {
1949 nsColor = null;
1950 } else {
1951 nsColor = NSColor.colorWithDeviceRed (color [0], color [1], color [2], 1);
1952 }
1953 ((NSTableView) view).setBackgroundColor (nsColor);
1724 } 1954 }
1725 1955
1726 /** 1956 /**
1727 * Sets the order that the items in the receiver should 1957 * Sets the order that the items in the receiver should
1728 * be displayed in to the given argument which is described 1958 * be displayed in to the given argument which is described
1764 if (seen [index]) error (DWT.ERROR_INVALID_ARGUMENT); 1994 if (seen [index]) error (DWT.ERROR_INVALID_ARGUMENT);
1765 seen [index] = true; 1995 seen [index] = true;
1766 if (order [i] !is oldOrder [i]) reorder = true; 1996 if (order [i] !is oldOrder [i]) reorder = true;
1767 } 1997 }
1768 if (reorder) { 1998 if (reorder) {
1769 int x = 0; 1999 NSTableView tableView = (NSTableView)view;
1770 short [] width = new short [1];
1771 int [] oldX = new int [oldOrder.length]; 2000 int [] oldX = new int [oldOrder.length];
2001 int check = (style & DWT.CHECK) !is 0 ? 1 : 0;
1772 for (int i=0; i<oldOrder.length; i++) { 2002 for (int i=0; i<oldOrder.length; i++) {
1773 int index = oldOrder [i]; 2003 int index = oldOrder[i];
1774 TableColumn column = columns [index]; 2004 oldX [index] = (int)tableView.rectOfColumn (i + check).x;
1775 oldX [index] = x; 2005 }
1776 // OS.GetDataBrowserTableViewNamedColumnWidth(handle, column.id, width);
1777 x += width [0];
1778 }
1779 x = 0;
1780 int [] newX = new int [order.length]; 2006 int [] newX = new int [order.length];
1781 for (int i=0; i<order.length; i++) { 2007 for (int i=0; i<order.length; i++) {
1782 int index = order [i]; 2008 int index = order [i];
1783 TableColumn column = columns [index]; 2009 TableColumn column = columns[index];
1784 int position = (style & DWT.CHECK) !is 0 ? i + 1 : i; 2010 int oldIndex = tableView.columnWithIdentifier (column.nsColumn);
1785 // OS.SetDataBrowserTableViewColumnPosition(handle, column.id, position); 2011 int newIndex = i + check;
1786 // column.lastPosition = position; 2012 tableView.moveColumn (oldIndex, newIndex);
1787 newX [index] = x; 2013 newX [index] = (int)tableView.rectOfColumn (newIndex).x;
1788 // OS.GetDataBrowserTableViewNamedColumnWidth(handle, column.id, width);
1789 x += width [0];
1790 } 2014 }
1791 TableColumn[] newColumns = new TableColumn [columnCount]; 2015 TableColumn[] newColumns = new TableColumn [columnCount];
1792 System.arraycopy (columns, 0, newColumns, 0, columnCount); 2016 System.arraycopy (columns, 0, newColumns, 0, columnCount);
1793 for (int i=0; i<columnCount; i++) { 2017 for (int i=0; i<columnCount; i++) {
1794 TableColumn column = newColumns [i]; 2018 TableColumn column = newColumns [i];
1799 } 2023 }
1800 } 2024 }
1801 } 2025 }
1802 } 2026 }
1803 2027
2028 void setFont(NSFont font) {
2029 super.setFont (font);
2030 if (!hooks (DWT.MeasureItem)) {
2031 float ascent = font.ascender ();
2032 float descent = -font.descender () + font.leading ();
2033 ((NSTableView)view).setRowHeight ((int)Math.ceil (ascent + descent) + 1);
2034 } else {
2035 view.setNeedsDisplay (true);
2036 }
2037 }
2038
1804 /** 2039 /**
1805 * Marks the receiver's header as visible if the argument is <code>true</code>, 2040 * Marks the receiver's header as visible if the argument is <code>true</code>,
1806 * and marks it invisible otherwise. 2041 * and marks it invisible otherwise.
1807 * <p> 2042 * <p>
1808 * If one of the receiver's ancestors is not visible or some 2043 * If one of the receiver's ancestors is not visible or some
1834 * 2069 *
1835 * @since 3.0 2070 * @since 3.0
1836 */ 2071 */
1837 public void setItemCount (int count) { 2072 public void setItemCount (int count) {
1838 checkWidget (); 2073 checkWidget ();
1839 // checkItems (true); 2074 count = Math.max (0, count);
1840 // count = Math.max (0, count); 2075 if (count is itemCount) return;
1841 // if (count is itemCount) return; 2076 if (count is itemCount) return;
1842 // setRedraw (false); 2077 TableItem [] children = items;
1843 // int[] top = new int [1], left = new int [1]; 2078 if (count < itemCount) {
1844 // OS.GetDataBrowserScrollPosition (handle, top, left); 2079 for (int index = count; index < itemCount; index ++) {
1845 // DataBrowserCallbacks callbacks = new DataBrowserCallbacks (); 2080 TableItem item = children [index];
1846 // OS.GetDataBrowserCallbacks (handle, callbacks); 2081 if (item !is null && !item.isDisposed()) item.release (false);
1847 // callbacks.v1_itemNotificationCallback = 0; 2082 }
1848 // callbacks.v1_itemCompareCallback = 0; 2083 }
1849 // OS.SetDataBrowserCallbacks (handle, callbacks); 2084 if (count > itemCount) {
1850 // if (count < itemCount) { 2085 if ((getStyle() & DWT.VIRTUAL) is 0) {
1851 // int index = count; 2086 for (int i=itemCount; i<count; i++) {
1852 // int[] id = new int [itemCount - count]; 2087 new TableItem (this, DWT.NONE, i, true);
1853 // while (index < itemCount) { 2088 }
1854 // TableItem item = items [index]; 2089 return;
1855 // if (item !is null) item.release (false); 2090 }
1856 // id [index-count] = index + 1; 2091 }
1857 // index++; 2092 int length = Math.max (4, (count + 3) / 4 * 4);
1858 // } 2093 TableItem [] newItems = new TableItem [length];
1859 // OS.RemoveDataBrowserItems (handle, OS.kDataBrowserNoItem, id.length, id, 0); 2094 if (children !is null) {
1860 // int [] newItemCount = new int [1]; 2095 System.arraycopy (items, 0, children, 0, Math.min (count, itemCount));
1861 // if (OS.GetDataBrowserItemCount (handle, OS.kDataBrowserNoItem, true, OS.kDataBrowserItemAnyState, newItemCount) !is OS.noErr) { 2096 }
1862 // error (DWT.ERROR_CANNOT_GET_COUNT); 2097 children = newItems;
1863 // } 2098 this.items = newItems;
1864 // if (count !is newItemCount[0]) error (DWT.ERROR_ITEM_NOT_REMOVED); 2099 this.itemCount = count;
1865 // } 2100 ((NSTableView) view).noteNumberOfRowsChanged ();
1866 // int length = Math.max (4, (count + 3) / 4 * 4);
1867 // TableItem [] newItems = new TableItem [length];
1868 // System.arraycopy (items, 0, newItems, 0, Math.min (count, itemCount));
1869 // items = newItems;
1870 // if ((style & DWT.VIRTUAL) is 0) {
1871 // for (int i=itemCount; i<count; i++) {
1872 // items [i] = new TableItem (this, DWT.NONE, i, false);
1873 // }
1874 // }
1875 // itemCount = count;
1876 // OS.AddDataBrowserItems (handle, 0, itemCount, null, OS.kDataBrowserItemNoProperty);
1877 // callbacks.v1_itemNotificationCallback = display.itemNotificationProc;
1878 // callbacks.v1_itemCompareCallback = itemCompareProc ();
1879 // OS.SetDataBrowserCallbacks (handle, callbacks);
1880 // fixScrollBar ();
1881 // setRedraw (true);
1882 } 2101 }
1883 2102
1884 /*public*/ void setItemHeight (int itemHeight) { 2103 /*public*/ void setItemHeight (int itemHeight) {
1885 checkWidget (); 2104 checkWidget ();
1886 if (itemHeight < -1) error (DWT.ERROR_INVALID_ARGUMENT); 2105 if (itemHeight < -1) error (DWT.ERROR_INVALID_ARGUMENT);
1887 if (itemHeight is -1) { 2106 if (itemHeight is -1) {
1888 //TODO - reset item height, ensure other API's such as setFont don't do this 2107 //TODO - reset item height, ensure other API's such as setFont don't do this
1889 } else { 2108 } else {
1890 // OS.SetDataBrowserTableViewRowHeight (handle, cast(short) itemHeight); 2109 // OS.SetDataBrowserTableViewRowHeight (handle, cast(short) itemHeight);
2110 }
2111 }
2112
2113 public void setRedraw (bool redraw) {
2114 checkWidget ();
2115 super.setRedraw (redraw);
2116 if (redraw && drawCount is 0) {
2117 setScrollWidth ();
1891 } 2118 }
1892 } 2119 }
1893 2120
1894 /** 2121 /**
1895 * Marks the receiver's lines as visible if the argument is <code>true</code>, 2122 * Marks the receiver's lines as visible if the argument is <code>true</code>,
1910 public void setLinesVisible (bool show) { 2137 public void setLinesVisible (bool show) {
1911 checkWidget (); 2138 checkWidget ();
1912 (cast(NSTableView)view).setUsesAlternatingRowBackgroundColors(show); 2139 (cast(NSTableView)view).setUsesAlternatingRowBackgroundColors(show);
1913 } 2140 }
1914 2141
1915 bool setScrollWidth (TableItem item) { 2142 bool setScrollWidth () {
2143 return setScrollWidth (items, true);
2144 }
2145
2146 bool setScrollWidth (TableItem item, bool callMeasureItem) {
2147 return setScrollWidth (new TableItem[] {item}, callMeasureItem);
2148 }
2149
2150 bool setScrollWidth (TableItem items[], bool callMeasureItem) {
1916 if (columnCount !is 0) return false; 2151 if (columnCount !is 0) return false;
1917 if (currentItem !is null) { 2152 if (currentItem !is null) {
1918 // if (currentItem !is item) fixScrollWidth = true; 2153 // if (currentItem !is item) fixScrollWidth = true;
1919 return false; 2154 return false;
1920 } 2155 }
1921 if (drawCount !is 0) return false; 2156 if (/*ignoreRedraw ||*/ drawCount !is 0) return false;
2157 int newWidth = 0;
1922 GC gc = new GC (this); 2158 GC gc = new GC (this);
1923 int newWidth = item.calculateWidth (0, gc); 2159 for (int i = 0; i < items.length; i++) {
2160 TableItem item = items[i];
2161 if (item !is null && !item.isDisposed ()) {
2162 newWidth = Math.max (newWidth, item.calculateWidth (0, gc, callMeasureItem));
2163 if (isDisposed ()) {
2164 gc.dispose ();
2165 return false;
2166 }
2167 }
2168 }
1924 gc.dispose (); 2169 gc.dispose ();
1925 newWidth += getInsetWidth (); 2170 newWidth += getInsetWidth ();
1926 // short [] width = new short [1]; 2171 if (firstColumn.width () < newWidth) {
1927 // OS.GetDataBrowserTableViewNamedColumnWidth (handle, column_id, width); 2172 NSTableView tableView = (NSTableView)view;
1928 // if (width [0] < newWidth) { 2173 int /*long*/ oldResize = tableView.columnAutoresizingStyle ();
1929 // OS.SetDataBrowserTableViewNamedColumnWidth (handle, column_id, cast(short) newWidth); 2174 tableView.setColumnAutoresizingStyle (OS.NSTableViewNoColumnAutoresizing);
1930 // return true;
1931 // }
1932 if (firstColumn.width() < newWidth) {
1933 firstColumn.setWidth (newWidth); 2175 firstColumn.setWidth (newWidth);
2176 tableView.setColumnAutoresizingStyle (oldResize);
2177 return true;
1934 } 2178 }
1935 return false; 2179 return false;
1936 }
1937
1938 bool setScrollWidth (TableItem [] items, bool set) {
1939 if (columnCount !is 0) return false;
1940 if (currentItem !is null) {
1941 // fixScrollWidth = true;
1942 return false;
1943 }
1944 if (drawCount !is 0) return false;
1945 GC gc = new GC (this);
1946 int newWidth = 0;
1947 for (int i = 0; i < items.length; i++) {
1948 TableItem item = items [i];
1949 if (item !is null) {
1950 newWidth = Math.max (newWidth, item.calculateWidth (0, gc));
1951 }
1952 }
1953 gc.dispose ();
1954 newWidth += getInsetWidth ();
1955 // if (!set) {
1956 // short [] width = new short [1];
1957 // OS.GetDataBrowserTableViewNamedColumnWidth (handle, column_id, width);
1958 // if (width [0] >= newWidth) return false;
1959 // }
1960 // OS.SetDataBrowserTableViewNamedColumnWidth (handle, column_id, cast(short) newWidth);
1961 if (!set) {
1962 if (firstColumn.width() > newWidth) return false;
1963 }
1964 firstColumn.setWidth (newWidth);
1965 return true;
1966 } 2180 }
1967 2181
1968 /** 2182 /**
1969 * Selects the item at the given zero-relative index in the receiver. 2183 * Selects the item at the given zero-relative index in the receiver.
1970 * The current selection is first cleared, then the new item is selected. 2184 * The current selection is first cleared, then the new item is selected.
1978 * 2192 *
1979 * @see Table#deselectAll() 2193 * @see Table#deselectAll()
1980 * @see Table#select(int) 2194 * @see Table#select(int)
1981 */ 2195 */
1982 public void setSelection (int index) { 2196 public void setSelection (int index) {
1983 checkWidget(); 2197 checkWidget ();
1984 //TODO - optimize to use expand flag 2198 //TODO - optimize to use expand flag
1985 deselectAll (); 2199 deselectAll ();
1986 setSelection (index, false); 2200 setSelection (index, false);
1987 } 2201 }
1988 2202
1989 void setSelection (int index, bool notify) { 2203 void setSelection (int index, bool notify) {
1990 // checkWidget(); 2204 // checkWidget ();
1991 if (0 <= index && index < itemCount) { 2205 if (0 <= index && index < itemCount) {
1992 select (index); 2206 select (index);
1993 showIndex (index); 2207 showIndex (index);
1994 if (notify) { 2208 if (notify) {
1995 Event event = new Event (); 2209 Event event = new Event ();
2156 */ 2370 */
2157 public void setSortColumn (TableColumn column) { 2371 public void setSortColumn (TableColumn column) {
2158 checkWidget (); 2372 checkWidget ();
2159 if (column !is null && column.isDisposed ()) error (DWT.ERROR_INVALID_ARGUMENT); 2373 if (column !is null && column.isDisposed ()) error (DWT.ERROR_INVALID_ARGUMENT);
2160 if (column is sortColumn) return; 2374 if (column is sortColumn) return;
2161 // DataBrowserCallbacks callbacks = new DataBrowserCallbacks (); 2375 TableColumn oldSortColumn = sortColumn;
2162 // OS.GetDataBrowserCallbacks (handle, callbacks); 2376 sortColumn = column;
2163 // callbacks.v1_itemCompareCallback = display.itemCompareProc; 2377 if (sortDirection is DWT.NONE) return;
2164 // OS.SetDataBrowserCallbacks (handle, callbacks); 2378 NSTableHeaderView headerView = ((NSTableView)view).headerView ();
2165 // if (column is null) { 2379 if (headerView is null) return;
2166 // if (sortColumn !is null && !sortColumn.isDisposed () && sortDirection !is DWT.NONE) { 2380 if (oldSortColumn !is null) {
2167 // OS.SetDataBrowserSortOrder (handle, cast(short) OS.kDataBrowserOrderIncreasing); 2381 NSInteger index = ((NSTableView)view).columnWithIdentifier (oldSortColumn.nsColumn);
2168 // sortColumn = null; 2382 NSRect rect = headerView.headerRectOfColumn (index);
2169 // OS.SetDataBrowserSortProperty (handle, 0); 2383 headerView.setNeedsDisplayInRect (rect);
2170 // } 2384 }
2171 // } 2385 if (sortColumn !is null) {
2172 // sortColumn = column; 2386 int /*long*/ index = ((NSTableView)view).columnWithIdentifier (sortColumn.nsColumn);
2173 // if (sortColumn !is null && !sortColumn.isDisposed () && sortDirection !is DWT.NONE) { 2387 NSRect rect = headerView.headerRectOfColumn (index);
2174 // OS.SetDataBrowserSortProperty (handle, sortColumn.id); 2388 headerView.setNeedsDisplayInRect (rect);
2175 // int order = sortDirection is DWT.DOWN ? OS.kDataBrowserOrderDecreasing : OS.kDataBrowserOrderIncreasing; 2389 }
2176 // OS.SetDataBrowserSortOrder (handle, cast(short) order);
2177 // }
2178 // callbacks.v1_itemCompareCallback = itemCompareProc ();
2179 // OS.SetDataBrowserCallbacks (handle, callbacks);
2180 } 2390 }
2181 2391
2182 /** 2392 /**
2183 * Sets the direction of the sort indicator for the receiver. The value 2393 * Sets the direction of the sort indicator for the receiver. The value
2184 * can be one of <code>UP</code>, <code>DOWN</code> or <code>NONE</code>. 2394 * can be one of <code>UP</code>, <code>DOWN</code> or <code>NONE</code>.
2195 public void setSortDirection (int direction) { 2405 public void setSortDirection (int direction) {
2196 checkWidget (); 2406 checkWidget ();
2197 if (direction !is DWT.UP && direction !is DWT.DOWN && direction !is DWT.NONE) return; 2407 if (direction !is DWT.UP && direction !is DWT.DOWN && direction !is DWT.NONE) return;
2198 if (direction is sortDirection) return; 2408 if (direction is sortDirection) return;
2199 sortDirection = direction; 2409 sortDirection = direction;
2200 // DataBrowserCallbacks callbacks = new DataBrowserCallbacks (); 2410 if (sortColumn is null) return;
2201 // OS.GetDataBrowserCallbacks (handle, callbacks); 2411 NSTableHeaderView headerView = ((NSTableView)view).headerView ();
2202 // callbacks.v1_itemCompareCallback = display.itemCompareProc; 2412 if (headerView is null) return;
2203 // OS.SetDataBrowserCallbacks (handle, callbacks); 2413 int /*long*/ index = ((NSTableView)view).columnWithIdentifier (sortColumn.nsColumn);
2204 // if (sortColumn !is null && !sortColumn.isDisposed ()) { 2414 NSRect rect = headerView.headerRectOfColumn (index);
2205 // if (sortDirection is DWT.NONE) { 2415 headerView.setNeedsDisplayInRect (rect);
2206 // OS.SetDataBrowserSortOrder (handle, cast(short) OS.kDataBrowserOrderIncreasing);
2207 // TableColumn column = sortColumn;
2208 // sortColumn = null;
2209 // OS.SetDataBrowserSortProperty (handle, 0);
2210 // sortColumn = column;
2211 // } else {
2212 // OS.SetDataBrowserSortProperty (handle, 0);
2213 // OS.SetDataBrowserSortProperty (handle, sortColumn.id);
2214 // int order = sortDirection is DWT.DOWN ? OS.kDataBrowserOrderDecreasing : OS.kDataBrowserOrderIncreasing;
2215 // OS.SetDataBrowserSortOrder (handle, cast(short) order);
2216 // }
2217 // }
2218 // callbacks.v1_itemCompareCallback = itemCompareProc ();
2219 // OS.SetDataBrowserCallbacks (handle, callbacks);
2220 } 2416 }
2221 2417
2222 void setTableEmpty () { 2418 void setTableEmpty () {
2223 itemCount = 0; 2419 itemCount = 0;
2224 items = new TableItem [4]; 2420 items = new TableItem [4];
2235 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 2431 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
2236 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 2432 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
2237 * </ul> 2433 * </ul>
2238 */ 2434 */
2239 public void setTopIndex (int index) { 2435 public void setTopIndex (int index) {
2240 checkWidget(); 2436 checkWidget ();
2241 NSRect rect = (cast(NSTableView)view).rectOfRow(index); 2437 NSRect rect = (cast(NSTableView)view).rectOfRow(index);
2242 (cast(NSTableView)view).scrollRectToVisible(rect); 2438 (cast(NSTableView)view).scrollRectToVisible(rect);
2243 } 2439 }
2244 2440
2245 /** 2441 /**
2263 public void showColumn (TableColumn column) { 2459 public void showColumn (TableColumn column) {
2264 checkWidget (); 2460 checkWidget ();
2265 if (column is null) error (DWT.ERROR_NULL_ARGUMENT); 2461 if (column is null) error (DWT.ERROR_NULL_ARGUMENT);
2266 if (column.isDisposed()) error(DWT.ERROR_INVALID_ARGUMENT); 2462 if (column.isDisposed()) error(DWT.ERROR_INVALID_ARGUMENT);
2267 if (column.parent !is this) return; 2463 if (column.parent !is this) return;
2268 int index = indexOf (column); 2464 if (columnCount <= 1) return;
2269 if (columnCount <= 1 || !(0 <= index && index < columnCount)) return; 2465 int index = (int)/*64*/((NSTableView)view).columnWithIdentifier (column.nsColumn);
2270 (cast(NSTableView)view).scrollColumnToVisible(index + ((style & DWT.CHECK) !is 0 ? 1 : 0)); 2466 if (!(0 <= index && index < columnCount + ((style & DWT.CHECK) !is 0 ? 1 : 0))) return;
2467 ((NSTableView)view).scrollColumnToVisible (index);
2271 } 2468 }
2272 2469
2273 void showIndex (int index) { 2470 void showIndex (int index) {
2274 if (0 <= index && index < itemCount) { 2471 if (0 <= index && index < itemCount) {
2275 (cast(NSTableView)view).scrollRowToVisible(index); 2472 (cast(NSTableView)view).scrollRowToVisible(index);
2313 * </ul> 2510 * </ul>
2314 * 2511 *
2315 * @see Table#showItem(TableItem) 2512 * @see Table#showItem(TableItem)
2316 */ 2513 */
2317 public void showSelection () { 2514 public void showSelection () {
2318 checkWidget(); 2515 checkWidget ();
2319 int index = getSelectionIndex (); 2516 int index = getSelectionIndex ();
2320 if (index >= 0) showIndex (index); 2517 if (index >= 0) showIndex (index);
2321 } 2518 }
2322 2519
2323 void sendDoubleSelection() { 2520 void sendDoubleSelection() {
2324 postEvent (DWT.DefaultSelection); 2521 postEvent (DWT.DefaultSelection);
2325 } 2522 }
2326 2523
2327 void tableViewSelectionDidChange (int aNotification) { 2524 bool sendKeyEvent (NSEvent nsEvent, int type) {
2525 bool result = super.sendKeyEvent (nsEvent, type);
2526 if (!result) return result;
2527 if (type !is DWT.KeyDown) return result;
2528 short keyCode = nsEvent.keyCode ();
2529 switch (keyCode) {
2530 case 76: /* KP Enter */
2531 case 36: { /* Return */
2532 postEvent (DWT.DefaultSelection);
2533 break;
2534 }
2535 }
2536 return result;
2537 }
2538
2539 void tableViewColumnDidMove (int /*long*/ id, int /*long*/ sel, int /*long*/ aNotification) {
2540 NSNotification notification = new NSNotification (aNotification);
2541 NSDictionary userInfo = notification.userInfo ();
2542 id nsOldIndex = userInfo.valueForKey (NSString.stringWith ("NSOldColumn")); //$NON-NLS-1$
2543 id nsNewIndex = userInfo.valueForKey (NSString.stringWith ("NSNewColumn")); //$NON-NLS-1$
2544 int oldIndex = new NSNumber (nsOldIndex).intValue ();
2545 int newIndex = new NSNumber (nsNewIndex).intValue ();
2546 int startIndex = Math.min (oldIndex, newIndex);
2547 int endIndex = Math.max (oldIndex, newIndex);
2548 NSTableView tableView = (NSTableView)view;
2549 NSArray nsColumns = tableView.tableColumns ();
2550 for (int i = startIndex; i <= endIndex; i++) {
2551 id columnId = nsColumns.objectAtIndex (i);
2552 TableColumn column = getColumn (columnId);
2553 if (column !is null) {
2554 column.sendEvent (DWT.Move);
2555 if (isDisposed ()) return;
2556 }
2557 }
2558 }
2559
2560 void tableViewColumnDidResize (int /*long*/ id, int /*long*/ sel, int /*long*/ aNotification) {
2561 NSNotification notification = new NSNotification (aNotification);
2562 NSDictionary userInfo = notification.userInfo ();
2563 id columnId = userInfo.valueForKey (NSString.stringWith ("NSTableColumn")); //$NON-NLS-1$
2564 TableColumn column = getColumn (columnId);
2565 if (column is null) return; /* either CHECK column or firstColumn in 0-column Table */
2566
2567 column.sendEvent (DWT.Resize);
2568 if (isDisposed ()) return;
2569
2570 NSTableView tableView = (NSTableView)view;
2571 int index = (int)/*64*/tableView.columnWithIdentifier (columnId);
2572 if (index is -1) return; /* column was disposed in Resize callback */
2573
2574 NSArray nsColumns = tableView.tableColumns ();
2575 int columnCount = (int)/*64*/tableView.numberOfColumns ();
2576 for (int i = index + 1; i < columnCount; i++) {
2577 columnId = nsColumns.objectAtIndex (i);
2578 column = getColumn (columnId);
2579 if (column !is null) {
2580 column.sendEvent (DWT.Move);
2581 if (isDisposed ()) return;
2582 }
2583 }
2584 }
2585
2586 void tableViewSelectionDidChange (int /*long*/ id, int /*long*/ sel, int /*long*/ aNotification) {
2328 if (ignoreSelect) return; 2587 if (ignoreSelect) return;
2329 NSTableView widget = cast(NSTableView)view; 2588 NSTableView widget = cast(NSTableView) view;
2330 int row = widget.selectedRow(); 2589 int row = (int)/*64*/widget.selectedRow ();
2331 if(row is -1) 2590 if(row is -1)
2332 postEvent(DWT.Selection); 2591 postEvent (DWT.Selection);
2333 else { 2592 else {
2334 TableItem item = _getItem(row); 2593 TableItem item = _getItem (row);
2335 Event event = new Event(); 2594 Event event = new Event ();
2336 event.item = item; 2595 event.item = item;
2337 event.index = row; 2596 event.index = row;
2338 postEvent(DWT.Selection, event); 2597 postEvent (DWT.Selection, event);
2339 } 2598 }
2340 } 2599 }
2341 2600
2342 int tableView_objectValueForTableColumn_row(int aTableView, int aTableColumn, int rowIndex) { 2601 void tableView_didClickTableColumn (int /*long*/ id, int /*long*/ sel, int /*long*/ tableView, int /*long*/ tableColumn) {
2343 TableItem item = items [rowIndex]; 2602 TableColumn column = getColumn (new id (tableColumn));
2603 column.postEvent (DWT.Selection);
2604 }
2605
2606 int /*long*/ tableView_objectValueForTableColumn_row (int /*long*/ id, int /*long*/ sel, int /*long*/ aTableView, int /*long*/ aTableColumn, int /*long*/ rowIndex) {
2607 TableItem item = _getItem ((int)/*64*/rowIndex);
2344 if (checkColumn !is null && aTableColumn is checkColumn.id) { 2608 if (checkColumn !is null && aTableColumn is checkColumn.id) {
2345 NSNumber value; 2609 NSNumber value;
2346 if (item.checked && item.grayed) { 2610 if (item.checked && item.grayed) {
2347 value = NSNumber.numberWithInt(OS.NSMixedState); 2611 value = NSNumber.numberWithInt (OS.NSMixedState);
2348 } else { 2612 } else {
2349 value = NSNumber.numberWithInt(item.checked ? OS.NSOnState : OS.NSOffState); 2613 value = NSNumber.numberWithInt (item.checked ? OS.NSOnState : OS.NSOffState);
2350 } 2614 }
2351 return value.id; 2615 return value.id;
2352 } 2616 }
2353 for (int i=0; i<columnCount; i++) { 2617 for (int i=0; i<columnCount; i++) {
2354 if (columns [i].nsColumn.id is aTableColumn) { 2618 if (columns [i].nsColumn.id is aTableColumn) {
2355 return item.createString(i).id; 2619 return item.createString (i).id;
2356 } 2620 }
2357 } 2621 }
2358 return item.createString(0).id; 2622 return item.createString (0).id;
2359 } 2623 }
2360 2624
2361 void tableView_setObjectValue_forTableColumn_row(int aTableView, int anObject, int aTableColumn, int rowIndex) { 2625 void tableView_setObjectValue_forTableColumn_row (int /*long*/ id, int /*long*/ sel, int /*long*/ aTableView, int /*long*/ anObject, int /*long*/ aTableColumn, int /*long*/ rowIndex) {
2362 TableItem item = items [rowIndex];
2363 if (checkColumn !is null && aTableColumn is checkColumn.id) { 2626 if (checkColumn !is null && aTableColumn is checkColumn.id) {
2627 TableItem item = items [(int)/*64*/rowIndex];
2364 item.checked = !item.checked; 2628 item.checked = !item.checked;
2365 Event event = new Event(); 2629 Event event = new Event ();
2366 event.detail = DWT.CHECK; 2630 event.detail = DWT.CHECK;
2367 event.item = item; 2631 event.item = item;
2368 event.index = rowIndex; 2632 event.index = (int)/*64*/rowIndex;
2369 postEvent(DWT.Selection, event); 2633 postEvent (DWT.Selection, event);
2370 } 2634 NSTableView tableView = (NSTableView)view;
2371 } 2635 NSRect rect = tableView.rectOfRow (rowIndex);
2372 2636 tableView.setNeedsDisplayInRect (rect);
2373 bool tableView_shouldEditTableColumn_row(int aTableView, int aTableColumn, int rowIndex) { 2637 }
2638 }
2639
2640 bool tableView_shouldEditTableColumn_row (int /*long*/ id, int /*long*/ sel, int /*long*/ aTableView, int /*long*/ aTableColumn, int /*long*/ rowIndex) {
2374 return false; 2641 return false;
2375 } 2642 }
2376 2643
2377 void tableView_willDisplayCell_forTableColumn_row(int aTableView, int aCell, int aTableColumn, int rowIndex) { 2644 void tableView_willDisplayCell_forTableColumn_row (int /*long*/ id, int /*long*/ sel, int /*long*/ aTableView, int /*long*/ aCell, int /*long*/ aTableColumn, int /*long*/ rowIndex) {
2378 if (checkColumn !is null && aTableColumn is checkColumn.id) return; 2645 if (checkColumn !is null && aTableColumn is checkColumn.id) return;
2379 TableItem item = items [rowIndex]; 2646 TableItem item = items [(int)/*64*/rowIndex];
2380 Image image = item.image; 2647 Image image = item.image;
2648 int columnIndex = 0;
2381 for (int i=0; i<columnCount; i++) { 2649 for (int i=0; i<columnCount; i++) {
2382 if (columns [i].nsColumn.id is aTableColumn) { 2650 if (columns [i].nsColumn.id is aTableColumn) {
2383 image = item.getImage(i); 2651 image = item.getImage (i);
2384 } 2652 columnIndex = i;
2385 } 2653 }
2386 NSBrowserCell cell = new NSBrowserCell(aCell); 2654 }
2387 cell.setImage(image !is null ? image.handle : null); 2655 NSBrowserCell cell = new NSBrowserCell (aCell);
2388 cell.setLeaf(true); 2656 cell.setFont (item.getFont (columnIndex).handle);
2389 } 2657 cell.setImage (image !is null ? image.handle : null);
2390 } 2658 cell.setLeaf (true);
2659
2660 if (hooks (DWT.MeasureItem)) {
2661 NSTableView tableView = (NSTableView)this.view;
2662 int nsColumnIndex = (int)/*64*/tableView.columnWithIdentifier (new id (aTableColumn));
2663 NSRect rect = tableView.frameOfCellAtColumn (nsColumnIndex, rowIndex);
2664 NSRect contentRect = cell.titleRectForBounds (rect);
2665 NSSize contentSize = cell.cellSizeForBounds (rect);
2666
2667 GCData data = new GCData ();
2668 data.paintRect = tableView.frame ();
2669 GC gc = GC.cocoa_new (this, data);
2670 gc.setFont (item.getFont (columnIndex));
2671 int rowHeight = (int)tableView.rowHeight ();
2672 Event event = new Event ();
2673 event.item = item;
2674 event.gc = gc;
2675 event.index = columnIndex;
2676 event.x = (int)contentRect.x;
2677 event.y = (int)contentRect.y;
2678 event.width = (int)Math.ceil (contentSize.width);
2679 event.height = rowHeight;
2680 sendEvent (DWT.MeasureItem, event);
2681 gc.dispose ();
2682 if (isDisposed ()) return;
2683 if (rowHeight < event.height) {
2684 tableView.setRowHeight(event.height);
2685 }
2686 if (columnCount is 0) {
2687 int change = event.width - (item.customWidth !is -1 ? item.customWidth : (int)Math.ceil (contentSize.width));
2688 if (item.customWidth !is -1 || event.width !is (int)Math.ceil (contentSize.width)) {
2689 item.customWidth = event.width;
2690 }
2691 if (change !is 0) setScrollWidth (item, false);
2692 }
2693 }
2694 }
2695 }