1 11 package org.eclipse.debug.internal.ui.viewers.model; 12 13 import org.eclipse.swt.SWT; 14 import org.eclipse.swt.events.SelectionListener; 15 import org.eclipse.swt.graphics.Color; 16 import org.eclipse.swt.graphics.GC; 17 import org.eclipse.swt.graphics.Image; 18 import org.eclipse.swt.graphics.Point; 19 import org.eclipse.swt.graphics.Rectangle; 20 import org.eclipse.swt.widgets.Canvas; 21 import org.eclipse.swt.widgets.Display; 22 import org.eclipse.swt.widgets.Event; 23 import org.eclipse.swt.widgets.Listener; 24 import org.eclipse.swt.widgets.ScrollBar; 25 import org.eclipse.swt.widgets.Tree; 26 import org.eclipse.swt.widgets.TreeColumn; 27 import org.eclipse.swt.widgets.TreeItem; 28 import org.eclipse.swt.widgets.TypedListener; 29 30 147 public class TreeCursor extends Canvas { 148 Tree tree; 149 TreeItem row = null; 150 TreeColumn column = null; 151 Listener treeListener, resizeListener, disposeItemListener, disposeColumnListener; 152 153 static final int BACKGROUND = SWT.COLOR_LIST_SELECTION_TEXT; 155 static final int FOREGROUND = SWT.COLOR_LIST_SELECTION; 156 157 185 public TreeCursor(Tree parent, int style) { 186 super(parent, style); 187 tree = parent; 188 setBackground(null); 189 setForeground(null); 190 191 Listener listener = new Listener() { 192 public void handleEvent(Event event) { 193 switch (event.type) { 194 case SWT.Dispose : 195 dispose(event); 196 break; 197 case SWT.FocusIn : 198 case SWT.FocusOut : 199 redraw(); 200 break; 201 case SWT.KeyDown : 202 keyDown(event); 203 break; 204 case SWT.Paint : 205 paint(event); 206 break; 207 case SWT.Traverse : 208 traverse(event); 209 break; 210 } 211 } 212 }; 213 int[] events = new int[] {SWT.Dispose, SWT.FocusIn, SWT.FocusOut, SWT.KeyDown, SWT.Paint, SWT.Traverse}; 214 for (int i = 0; i < events.length; i++) { 215 addListener(events[i], listener); 216 } 217 218 treeListener = new Listener() { 219 public void handleEvent(Event event) { 220 switch (event.type) { 221 case SWT.MouseDown : 222 tableMouseDown(event); 223 break; 224 case SWT.FocusIn : 225 tableFocusIn(event); 226 break; 227 } 228 } 229 }; 230 tree.addListener(SWT.FocusIn, treeListener); 231 tree.addListener(SWT.MouseDown, treeListener); 232 233 disposeItemListener = new Listener() { 234 public void handleEvent(Event event) { 235 row = null; 236 column = null; 237 _resize(); 238 } 239 }; 240 disposeColumnListener = new Listener() { 241 public void handleEvent(Event event) { 242 row = null; 243 column = null; 244 _resize(); 245 } 246 }; 247 resizeListener = new Listener() { 248 public void handleEvent(Event event) { 249 _resize(); 250 } 251 }; 252 ScrollBar hBar = tree.getHorizontalBar(); 253 if (hBar != null) { 254 hBar.addListener(SWT.Selection, resizeListener); 255 } 256 ScrollBar vBar = tree.getVerticalBar(); 257 if (vBar != null) { 258 vBar.addListener(SWT.Selection, resizeListener); 259 } 260 } 261 262 289 public void addSelectionListener(SelectionListener listener) { 290 checkWidget(); 291 if (listener == null) 292 SWT.error(SWT.ERROR_NULL_ARGUMENT); 293 TypedListener typedListener = new TypedListener(listener); 294 addListener(SWT.Selection, typedListener); 295 addListener(SWT.DefaultSelection, typedListener); 296 } 297 298 void dispose(Event event) { 299 tree.removeListener(SWT.FocusIn, treeListener); 300 tree.removeListener(SWT.MouseDown, treeListener); 301 if (column != null) { 302 column.removeListener(SWT.Dispose, disposeColumnListener); 303 column.removeListener(SWT.Move, resizeListener); 304 column.removeListener(SWT.Resize, resizeListener); 305 column = null; 306 } 307 if (row != null) { 308 row.removeListener(SWT.Dispose, disposeItemListener); 309 row = null; 310 } 311 ScrollBar hBar = tree.getHorizontalBar(); 312 if (hBar != null) { 313 hBar.removeListener(SWT.Selection, resizeListener); 314 } 315 ScrollBar vBar = tree.getVerticalBar(); 316 if (vBar != null) { 317 vBar.removeListener(SWT.Selection, resizeListener); 318 } 319 } 320 321 void keyDown(Event event) { 322 if (row == null) return; 323 switch (event.character) { 324 case SWT.CR : 325 notifyListeners(SWT.DefaultSelection, new Event()); 326 return; 327 } 328 int rowIndex = tree.indexOf(row); 329 int columnIndex = column == null ? 0 : tree.indexOf(column); 330 switch (event.keyCode) { 331 case SWT.ARROW_UP : 332 setRowColumn(Math.max(0, rowIndex - 1), columnIndex, true); 333 break; 334 case SWT.ARROW_DOWN : 335 setRowColumn(Math.min(rowIndex + 1, tree.getItemCount() - 1), columnIndex, true); 336 break; 337 case SWT.ARROW_LEFT : 338 case SWT.ARROW_RIGHT : 339 { 340 int columnCount = tree.getColumnCount(); 341 if (columnCount == 0) break; 342 int[] order = tree.getColumnOrder(); 343 int index = 0; 344 while (index < order.length) { 345 if (order[index] == columnIndex) break; 346 index++; 347 } 348 if (index == order.length) index = 0; 349 int leadKey = (getStyle() & SWT.RIGHT_TO_LEFT) != 0 ? SWT.ARROW_RIGHT : SWT.ARROW_LEFT; 350 if (event.keyCode == leadKey) { 351 setRowColumn(rowIndex, order[Math.max(0, index - 1)], true); 352 } else { 353 setRowColumn(rowIndex, order[Math.min(columnCount - 1, index + 1)], true); 354 } 355 break; 356 } 357 case SWT.HOME : 358 setRowColumn(0, columnIndex, true); 359 break; 360 case SWT.END : 361 { 362 int i = tree.getItemCount() - 1; 363 setRowColumn(i, columnIndex, true); 364 break; 365 } 366 case SWT.PAGE_UP : 367 { 368 int index = tree.indexOf(tree.getTopItem()); 369 if (index == rowIndex) { 370 Rectangle rect = tree.getClientArea(); 371 TreeItem item = tree.getItem(index); 372 Rectangle itemRect = item.getBounds(0); 373 rect.height -= itemRect.y; 374 int height = tree.getItemHeight(); 375 int page = Math.max(1, rect.height / height); 376 index = Math.max(0, index - page + 1); 377 } 378 setRowColumn(index, columnIndex, true); 379 break; 380 } 381 case SWT.PAGE_DOWN : 382 { 383 int index = tree.indexOf(tree.getTopItem()); 384 Rectangle rect = tree.getClientArea(); 385 TreeItem item = tree.getItem(index); 386 Rectangle itemRect = item.getBounds(0); 387 rect.height -= itemRect.y; 388 int height = tree.getItemHeight(); 389 int page = Math.max(1, rect.height / height); 390 int end = tree.getItemCount() - 1; 391 index = Math.min(end, index + page - 1); 392 if (index == rowIndex) { 393 index = Math.min(end, index + page - 1); 394 } 395 setRowColumn(index, columnIndex, true); 396 break; 397 } 398 } 399 } 400 401 void paint(Event event) { 402 if (row == null) return; 403 int columnIndex = column == null ? 0 : tree.indexOf(column); 404 GC gc = event.gc; 405 Display display = getDisplay(); 406 gc.setBackground(getBackground()); 407 gc.setForeground(getForeground()); 408 gc.fillRectangle(event.x, event.y, event.width, event.height); 409 int x = 0; 410 Point size = getSize(); 411 Image image = row.getImage(columnIndex); 412 if (image != null) { 413 Rectangle imageSize = image.getBounds(); 414 int imageY = (size.y - imageSize.height) / 2; 415 gc.drawImage(image, x, imageY); 416 x += imageSize.width; 417 } 418 String text = row.getText(columnIndex); 419 if (text != "") { Rectangle bounds = row.getBounds(columnIndex); 421 Point extent = gc.stringExtent(text); 422 String platform = SWT.getPlatform(); 424 if ("win32".equals(platform)) { if (tree.getColumnCount() == 0 || columnIndex == 0) { 426 x += 2; 427 } else { 428 int alignmnent = column.getAlignment(); 429 switch (alignmnent) { 430 case SWT.LEFT: 431 x += 6; 432 break; 433 case SWT.RIGHT: 434 x = bounds.width - extent.x - 6; 435 break; 436 case SWT.CENTER: 437 x += (bounds.width - x - extent.x) / 2; 438 break; 439 } 440 } 441 } else { 442 if (tree.getColumnCount() == 0) { 443 x += 5; 444 } else { 445 int alignmnent = column.getAlignment(); 446 switch (alignmnent) { 447 case SWT.LEFT: 448 x += 5; 449 break; 450 case SWT.RIGHT: 451 x = bounds.width- extent.x - 2; 452 break; 453 case SWT.CENTER: 454 x += (bounds.width - x - extent.x) / 2 + 2; 455 break; 456 } 457 } 458 } 459 int textY = (size.y - extent.y) / 2; 460 gc.drawString(text, x, textY); 461 } 462 if (isFocusControl()) { 463 gc.setBackground(display.getSystemColor(SWT.COLOR_BLACK)); 464 gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE)); 465 gc.drawFocus(0, 0, size.x, size.y); 466 } 467 } 468 469 void tableFocusIn(Event event) { 470 if (isDisposed()) 471 return; 472 if (isVisible()) 473 setFocus(); 474 } 475 476 void tableMouseDown(Event event) { 477 if (isDisposed() || !isVisible()) return; 478 Point pt = new Point(event.x, event.y); 479 int lineWidth = tree.getLinesVisible() ? tree.getGridLineWidth() : 0; 480 TreeItem item = tree.getItem(pt); 481 if ((tree.getStyle() & SWT.FULL_SELECTION) != 0) { 482 if (item == null) return; 483 } else { 484 int start = item != null ? tree.indexOf(item) : tree.indexOf(tree.getTopItem()); 485 int end = tree.getItemCount(); 486 Rectangle clientRect = tree.getClientArea(); 487 for (int i = start; i < end; i++) { 488 TreeItem nextItem = tree.getItem(i); 489 Rectangle rect = nextItem.getBounds(0); 490 if (pt.y >= rect.y && pt.y < rect.y + rect.height + lineWidth) { 491 item = nextItem; 492 break; 493 } 494 if (rect.y > clientRect.y + clientRect.height) return; 495 } 496 if (item == null) return; 497 } 498 TreeColumn newColumn = null; 499 int columnCount = tree.getColumnCount(); 500 if (columnCount > 0) { 501 for (int i = 0; i < columnCount; i++) { 502 Rectangle rect = item.getBounds(i); 503 rect.width += lineWidth; 504 rect.height += lineWidth; 505 if (rect.contains(pt)) { 506 newColumn = tree.getColumn(i); 507 break; 508 } 509 } 510 if (newColumn == null) { 511 newColumn = tree.getColumn(0); 512 } 513 } 514 setRowColumn(item, newColumn, true); 515 setFocus(); 516 return; 517 } 518 519 void traverse(Event event) { 520 switch (event.detail) { 521 case SWT.TRAVERSE_ARROW_NEXT : 522 case SWT.TRAVERSE_ARROW_PREVIOUS : 523 case SWT.TRAVERSE_RETURN : 524 event.doit = false; 525 return; 526 } 527 event.doit = true; 528 } 529 void setRowColumn(int row, int column, boolean notify) { 530 TreeItem item = row == -1 ? null : tree.getItem(row); 531 TreeColumn col = column == -1 || tree.getColumnCount() == 0 ? null : tree.getColumn(column); 532 setRowColumn(item, col, notify); 533 } 534 void setRowColumn(TreeItem row, TreeColumn column, boolean notify) { 535 if (this.row == row && this.column == column) { 536 return; 537 } 538 if (this.row != null && this.row != row) { 539 this.row.removeListener(SWT.Dispose, disposeItemListener); 540 this.row = null; 541 } 542 if (this.column != null && this.column != column) { 543 this.column.removeListener(SWT.Dispose, disposeColumnListener); 544 this.column.removeListener(SWT.Move, resizeListener); 545 this.column.removeListener(SWT.Resize, resizeListener); 546 this.column = null; 547 } 548 if (row != null) { 549 if (this.row != row) { 550 this.row = row; 551 row.addListener(SWT.Dispose, disposeItemListener); 552 tree.showItem(row); 553 } 554 if (this.column != column && column != null) { 555 this.column = column; 556 column.addListener(SWT.Dispose, disposeColumnListener); 557 column.addListener(SWT.Move, resizeListener); 558 column.addListener(SWT.Resize, resizeListener); 559 tree.showColumn(column); 560 } 561 int columnIndex = column == null ? 0 : tree.indexOf(column); 562 setBounds(row.getBounds(columnIndex)); 563 redraw(); 564 if (notify) { 565 notifyListeners(SWT.Selection, new Event()); 566 } 567 } 568 } 569 570 public void setVisible(boolean visible) { 571 checkWidget(); 572 if (visible) _resize(); 573 super.setVisible(visible); 574 } 575 576 595 public void removeSelectionListener(SelectionListener listener) { 596 checkWidget(); 597 if (listener == null) { 598 SWT.error(SWT.ERROR_NULL_ARGUMENT); 599 } 600 removeListener(SWT.Selection, listener); 601 removeListener(SWT.DefaultSelection, listener); 602 } 603 604 void _resize() { 605 if (row == null) { 606 setBounds(-200, -200, 0, 0); 607 } else { 608 int columnIndex = column == null ? 0 : tree.indexOf(column); 609 setBounds(row.getBounds(columnIndex)); 610 } 611 } 612 622 public int getColumn() { 623 checkWidget(); 624 return column == null ? 0 : tree.indexOf(column); 625 } 626 636 public TreeItem getRow() { 637 checkWidget(); 638 return row; 639 } 640 public void setBackground (Color color) { 641 if (color == null) color = getDisplay().getSystemColor(BACKGROUND); 642 super.setBackground(color); 643 redraw(); 644 } 645 public void setForeground (Color color) { 646 if (color == null) color = getDisplay().getSystemColor(FOREGROUND); 647 super.setForeground(color); 648 redraw(); 649 } 650 662 public void setSelection(int row, int column) { 663 checkWidget(); 664 int columnCount = tree.getColumnCount(); 665 int maxColumnIndex = columnCount == 0 ? 0 : columnCount - 1; 666 if (row < 0 667 || row >= tree.getItemCount() 668 || column < 0 669 || column > maxColumnIndex) 670 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 671 setRowColumn(row, column, false); 672 } 673 685 public void setSelection(TreeItem row, int column) { 686 checkWidget(); 687 int columnCount = tree.getColumnCount(); 688 int maxColumnIndex = columnCount == 0 ? 0 : columnCount - 1; 689 if (row == null 690 || row.isDisposed() 691 || column < 0 692 || column > maxColumnIndex) 693 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 694 setRowColumn(tree.indexOf(row), column, false); 695 } 696 } 697 | Popular Tags |