1 11 12 package org.eclipse.jface.window; 13 14 import java.util.HashMap ; 15 16 import org.eclipse.jface.viewers.ColumnViewer; 17 import org.eclipse.jface.viewers.ViewerCell; 18 import org.eclipse.swt.SWT; 19 import org.eclipse.swt.events.DisposeEvent; 20 import org.eclipse.swt.events.DisposeListener; 21 import org.eclipse.swt.graphics.Point; 22 import org.eclipse.swt.graphics.Rectangle; 23 import org.eclipse.swt.layout.FillLayout; 24 import org.eclipse.swt.widgets.Composite; 25 import org.eclipse.swt.widgets.Control; 26 import org.eclipse.swt.widgets.Event; 27 import org.eclipse.swt.widgets.Listener; 28 import org.eclipse.swt.widgets.Monitor; 29 import org.eclipse.swt.widgets.Shell; 30 31 36 public abstract class ToolTip { 37 private Control control; 38 39 private int xShift = 3; 40 41 private int yShift = 0; 42 43 private int popupDelay = 0; 44 45 private int hideDelay = 0; 46 47 private ToolTipOwnerControlListener listener; 48 49 private HashMap data; 50 51 private static Shell CURRENT_TOOLTIP; 53 54 57 public static final int RECREATE = 1; 58 59 63 public static final int NO_RECREATE = 1 << 1; 64 65 private TooltipHideListener hideListener = new TooltipHideListener(); 66 67 private boolean hideOnMouseDown = true; 68 69 private boolean respectDisplayBounds = true; 70 71 private boolean respectMonitorBounds = true; 72 73 private int style; 74 75 private Object currentArea; 76 77 83 public ToolTip(Control control) { 84 this(control, RECREATE, false); 85 } 86 87 99 public ToolTip(Control control, int style, boolean manualActivation) { 100 this.control = control; 101 this.style = style; 102 this.control.addDisposeListener(new DisposeListener() { 103 104 public void widgetDisposed(DisposeEvent e) { 105 deactivate(); 106 } 107 108 }); 109 110 this.listener = new ToolTipOwnerControlListener(); 111 112 if (!manualActivation) { 113 activate(); 114 } 115 } 116 117 125 public void setData(String key, Object value) { 126 if (data == null) { 127 data = new HashMap (); 128 } 129 data.put(key, value); 130 } 131 132 139 public Object getData(String key) { 140 if (data != null) { 141 return data.get(key); 142 } 143 return null; 144 } 145 146 154 public void setShift(Point p) { 155 xShift = p.x; 156 yShift = p.y; 157 } 158 159 162 public void activate() { 163 deactivate(); 164 control.addListener(SWT.Dispose, listener); 165 control.addListener(SWT.MouseHover, listener); 166 control.addListener(SWT.MouseMove, listener); 167 control.addListener(SWT.MouseExit, listener); 168 control.addListener(SWT.MouseDown, listener); 169 } 170 171 174 public void deactivate() { 175 control.removeListener(SWT.Dispose, listener); 176 control.removeListener(SWT.MouseHover, listener); 177 control.removeListener(SWT.MouseMove, listener); 178 control.removeListener(SWT.MouseExit, listener); 179 control.removeListener(SWT.MouseDown, listener); 180 } 181 182 187 public boolean isRespectDisplayBounds() { 188 return respectDisplayBounds; 189 } 190 191 201 public void setRespectDisplayBounds(boolean respectDisplayBounds) { 202 this.respectDisplayBounds = respectDisplayBounds; 203 } 204 205 210 public boolean isRespectMonitorBounds() { 211 return respectMonitorBounds; 212 } 213 214 225 public void setRespectMonitorBounds(boolean respectMonitorBounds) { 226 this.respectMonitorBounds = respectMonitorBounds; 227 } 228 229 239 protected boolean shouldCreateToolTip(Event event) { 240 if ((style & NO_RECREATE) != 0) { 241 Object tmp = getToolTipArea(event); 242 243 if (tmp == null) { 245 hide(); 246 return false; 247 } 248 249 boolean rv = !tmp.equals(currentArea); 250 return rv; 251 } 252 253 return true; 254 } 255 256 263 private boolean shouldHideToolTip(Event event) { 264 if (event != null && event.type == SWT.MouseMove 265 && (style & NO_RECREATE) != 0) { 266 Object tmp = getToolTipArea(event); 267 268 if (tmp == null) { 270 hide(); 271 return false; 272 } 273 274 boolean rv = !tmp.equals(currentArea); 275 return rv; 276 } 277 278 return true; 279 } 280 281 297 protected Object getToolTipArea(Event event) { 298 return control; 299 } 300 301 307 public void show(Point location) { 308 Event event = new Event(); 309 event.x = location.x; 310 event.y = location.y; 311 event.widget = control; 312 toolTipCreate(event); 313 } 314 315 private Shell toolTipCreate(final Event event) { 316 if (shouldCreateToolTip(event)) { 317 Shell shell = new Shell(control.getShell(), SWT.ON_TOP | SWT.TOOL 318 | SWT.NO_FOCUS); 319 shell.setLayout(new FillLayout()); 320 321 toolTipOpen(shell, event); 322 323 return shell; 324 } 325 326 return null; 327 } 328 329 private void toolTipShow(Shell tip, Event event) { 330 if (!tip.isDisposed()) { 331 currentArea = getToolTipArea(event); 332 createToolTipContentArea(event, tip); 333 if (isHideOnMouseDown()) { 334 toolTipHookBothRecursively(tip); 335 } else { 336 toolTipHookByTypeRecursively(tip, true, SWT.MouseExit); 337 } 338 339 tip.pack(); 340 tip.setLocation(fixupDisplayBounds(tip.getSize(), getLocation(tip 341 .getSize(), event))); 342 tip.setVisible(true); 343 } 344 } 345 346 private Point fixupDisplayBounds(Point tipSize, Point location) { 347 if (respectDisplayBounds || respectMonitorBounds) { 348 Rectangle bounds; 349 Point rightBounds = new Point(tipSize.x + location.x, tipSize.y 350 + location.y); 351 352 Monitor[] ms = control.getDisplay().getMonitors(); 353 354 if (respectMonitorBounds && ms.length > 1) { 355 bounds = control.getMonitor().getBounds(); 357 Point p = new Point(location.x, location.y); 358 359 Rectangle tmp; 361 for (int i = 0; i < ms.length; i++) { 362 tmp = ms[i].getBounds(); 363 if (tmp.contains(p)) { 364 bounds = tmp; 365 break; 366 } 367 } 368 369 } else { 370 bounds = control.getDisplay().getBounds(); 371 } 372 373 if (!(bounds.contains(location) && bounds.contains(rightBounds))) { 374 if (rightBounds.x > bounds.width) { 375 location.x -= rightBounds.x - bounds.width; 376 } 377 378 if (rightBounds.y > bounds.height) { 379 location.y -= rightBounds.y - bounds.height; 380 } 381 382 if (location.x < bounds.x) { 383 location.x = bounds.x; 384 } 385 386 if (location.y < bounds.y) { 387 location.y = bounds.y; 388 } 389 } 390 } 391 392 return location; 393 } 394 395 405 public Point getLocation(Point tipSize, Event event) { 406 return control.toDisplay(event.x + xShift, event.y + yShift); 407 } 408 409 private void toolTipHide(Shell tip, Event event) { 410 if (tip != null && !tip.isDisposed() && shouldHideToolTip(event)) { 411 currentArea = null; 412 tip.dispose(); 413 CURRENT_TOOLTIP = null; 414 afterHideToolTip(event); 415 } 416 } 417 418 private void toolTipOpen(final Shell shell, final Event event) { 419 if (CURRENT_TOOLTIP != null) { 421 toolTipHide(CURRENT_TOOLTIP, null); 422 } 423 424 CURRENT_TOOLTIP = shell; 425 426 if (popupDelay > 0) { 427 control.getDisplay().timerExec(popupDelay, new Runnable () { 428 public void run() { 429 toolTipShow(shell, event); 430 } 431 }); 432 } else { 433 toolTipShow(CURRENT_TOOLTIP, event); 434 } 435 436 if (hideDelay > 0) { 437 control.getDisplay().timerExec(popupDelay + hideDelay, 438 new Runnable () { 439 440 public void run() { 441 toolTipHide(shell, null); 442 } 443 }); 444 } 445 } 446 447 private void toolTipHookByTypeRecursively(Control c, boolean add, int type) { 448 if (add) { 449 c.addListener(type, hideListener); 450 } else { 451 c.removeListener(type, hideListener); 452 } 453 454 if (c instanceof Composite) { 455 Control[] children = ((Composite) c).getChildren(); 456 for (int i = 0; i < children.length; i++) { 457 toolTipHookByTypeRecursively(children[i], add, type); 458 } 459 } 460 } 461 462 private void toolTipHookBothRecursively(Control c) { 463 c.addListener(SWT.MouseDown, hideListener); 464 c.addListener(SWT.MouseExit, hideListener); 465 466 if (c instanceof Composite) { 467 Control[] children = ((Composite) c).getChildren(); 468 for (int i = 0; i < children.length; i++) { 469 toolTipHookBothRecursively(children[i]); 470 } 471 } 472 } 473 474 483 protected abstract Composite createToolTipContentArea(Event event, 484 Composite parent); 485 486 496 protected void afterHideToolTip(Event event) { 497 498 } 499 500 507 public void setHideDelay(int hideDelay) { 508 this.hideDelay = hideDelay; 509 } 510 511 518 public void setPopupDelay(int popupDelay) { 519 this.popupDelay = popupDelay; 520 } 521 522 527 public boolean isHideOnMouseDown() { 528 return hideOnMouseDown; 529 } 530 531 541 public void setHideOnMouseDown(final boolean hideOnMouseDown) { 542 if (CURRENT_TOOLTIP != null && !CURRENT_TOOLTIP.isDisposed()) { 544 if (hideOnMouseDown != this.hideOnMouseDown) { 546 control.getDisplay().syncExec(new Runnable () { 547 548 public void run() { 549 if (CURRENT_TOOLTIP != null 550 && CURRENT_TOOLTIP.isDisposed()) { 551 toolTipHookByTypeRecursively(CURRENT_TOOLTIP, 552 hideOnMouseDown, SWT.MouseDown); 553 } 554 } 555 556 }); 557 } 558 } 559 560 this.hideOnMouseDown = hideOnMouseDown; 561 } 562 563 566 public void hide() { 567 toolTipHide(CURRENT_TOOLTIP, null); 568 } 569 570 private class ToolTipOwnerControlListener implements Listener { 571 public void handleEvent(Event event) { 572 switch (event.type) { 573 case SWT.Dispose: 574 case SWT.KeyDown: 575 case SWT.MouseDown: 576 case SWT.MouseMove: 577 toolTipHide(CURRENT_TOOLTIP, event); 578 break; 579 case SWT.MouseHover: 580 toolTipCreate(event); 581 break; 582 case SWT.MouseExit: 583 587 if (CURRENT_TOOLTIP != null && !CURRENT_TOOLTIP.isDisposed()) { 588 if (CURRENT_TOOLTIP.getBounds().contains( 589 control.toDisplay(event.x, event.y))) { 590 break; 591 } 592 } 593 594 toolTipHide(CURRENT_TOOLTIP, event); 595 break; 596 } 597 } 598 } 599 600 private class TooltipHideListener implements Listener { 601 public void handleEvent(Event event) { 602 if (event.widget instanceof Control) { 603 604 Control c = (Control) event.widget; 605 Shell shell = c.getShell(); 606 607 switch (event.type) { 608 case SWT.MouseDown: 609 if (isHideOnMouseDown()) { 610 toolTipHide(shell, event); 611 } 612 break; 613 case SWT.MouseExit: 614 618 Rectangle rect = shell.getBounds(); 619 rect.x += 5; 620 rect.y += 5; 621 rect.width -= 10; 622 rect.height -= 10; 623 624 if (!rect.contains(c.getDisplay().getCursorLocation())) { 625 toolTipHide(shell, event); 626 } 627 628 break; 629 } 630 } 631 } 632 } 633 } 634 | Popular Tags |