1 11 package org.eclipse.swt.custom; 12 13 import org.eclipse.swt.*; 14 import org.eclipse.swt.widgets.*; 15 import org.eclipse.swt.graphics.*; 16 import org.eclipse.swt.events.*; 17 import org.eclipse.swt.accessibility.*; 18 19 42 public class CLabel extends Canvas { 43 44 45 private static final int GAP = 5; 46 47 private static final int INDENT = 3; 48 49 private static final String ELLIPSIS = "..."; 51 private int align = SWT.LEFT; 52 private int hIndent = INDENT; 53 private int vIndent = INDENT; 54 55 private String text; 56 57 private Image image; 58 private String appToolTipText; 64 65 private Image backgroundImage; 66 private Color[] gradientColors; 67 private int[] gradientPercents; 68 private boolean gradientVertical; 69 private Color background; 70 71 private static int DRAW_FLAGS = SWT.DRAW_MNEMONIC | SWT.DRAW_TAB | SWT.DRAW_TRANSPARENT | SWT.DRAW_DELIMITER; 72 73 104 public CLabel(Composite parent, int style) { 105 super(parent, checkStyle(style)); 106 if ((style & (SWT.CENTER | SWT.RIGHT)) == 0) style |= SWT.LEFT; 107 if ((style & SWT.CENTER) != 0) align = SWT.CENTER; 108 if ((style & SWT.RIGHT) != 0) align = SWT.RIGHT; 109 if ((style & SWT.LEFT) != 0) align = SWT.LEFT; 110 111 addPaintListener(new PaintListener(){ 112 public void paintControl(PaintEvent event) { 113 onPaint(event); 114 } 115 }); 116 117 addDisposeListener(new DisposeListener(){ 118 public void widgetDisposed(DisposeEvent event) { 119 onDispose(event); 120 } 121 }); 122 123 addTraverseListener(new TraverseListener() { 124 public void keyTraversed(TraverseEvent event) { 125 if (event.detail == SWT.TRAVERSE_MNEMONIC) { 126 onMnemonic(event); 127 } 128 } 129 }); 130 131 initAccessible(); 132 133 } 134 137 private static int checkStyle (int style) { 138 if ((style & SWT.BORDER) != 0) style |= SWT.SHADOW_IN; 139 int mask = SWT.SHADOW_IN | SWT.SHADOW_OUT | SWT.SHADOW_NONE | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT; 140 style = style & mask; 141 return style |= SWT.NO_FOCUS | SWT.DOUBLE_BUFFERED; 142 } 143 144 152 public Point computeSize(int wHint, int hHint, boolean changed) { 153 checkWidget(); 154 Point e = getTotalSize(image, text); 155 if (wHint == SWT.DEFAULT){ 156 e.x += 2*hIndent; 157 } else { 158 e.x = wHint; 159 } 160 if (hHint == SWT.DEFAULT) { 161 e.y += 2*vIndent; 162 } else { 163 e.y = hHint; 164 } 165 return e; 166 } 167 170 private void drawBevelRect(GC gc, int x, int y, int w, int h, Color topleft, Color bottomright) { 171 gc.setForeground(bottomright); 172 gc.drawLine(x+w, y, x+w, y+h); 173 gc.drawLine(x, y+h, x+w, y+h); 174 175 gc.setForeground(topleft); 176 gc.drawLine(x, y, x+w-1, y); 177 gc.drawLine(x, y, x, y+h-1); 178 } 179 184 char _findMnemonic (String string) { 185 if (string == null) return '\0'; 186 int index = 0; 187 int length = string.length (); 188 do { 189 while (index < length && string.charAt (index) != '&') index++; 190 if (++index >= length) return '\0'; 191 if (string.charAt (index) != '&') return Character.toLowerCase (string.charAt (index)); 192 index++; 193 } while (index < length); 194 return '\0'; 195 } 196 202 public int getAlignment() { 203 return align; 205 } 206 211 public Image getImage() { 212 return image; 214 } 215 218 private Point getTotalSize(Image image, String text) { 219 Point size = new Point(0, 0); 220 221 if (image != null) { 222 Rectangle r = image.getBounds(); 223 size.x += r.width; 224 size.y += r.height; 225 } 226 227 GC gc = new GC(this); 228 if (text != null && text.length() > 0) { 229 Point e = gc.textExtent(text, DRAW_FLAGS); 230 size.x += e.x; 231 size.y = Math.max(size.y, e.y); 232 if (image != null) size.x += GAP; 233 } else { 234 size.y = Math.max(size.y, gc.getFontMetrics().getHeight()); 235 } 236 gc.dispose(); 237 238 return size; 239 } 240 public int getStyle () { 241 int style = super.getStyle(); 242 switch (align) { 243 case SWT.RIGHT: style |= SWT.RIGHT; break; 244 case SWT.CENTER: style |= SWT.CENTER; break; 245 case SWT.LEFT: style |= SWT.LEFT; break; 246 } 247 return style; 248 } 249 250 255 public String getText() { 256 return text; 258 } 259 public String getToolTipText () { 260 checkWidget(); 261 return appToolTipText; 262 } 263 private void initAccessible() { 264 Accessible accessible = getAccessible(); 265 accessible.addAccessibleListener(new AccessibleAdapter() { 266 public void getName(AccessibleEvent e) { 267 e.result = getText(); 268 } 269 270 public void getHelp(AccessibleEvent e) { 271 e.result = getToolTipText(); 272 } 273 274 public void getKeyboardShortcut(AccessibleEvent e) { 275 char mnemonic = _findMnemonic(CLabel.this.text); 276 if (mnemonic != '\0') { 277 e.result = "Alt+"+mnemonic; } 279 } 280 }); 281 282 accessible.addAccessibleControlListener(new AccessibleControlAdapter() { 283 public void getChildAtPoint(AccessibleControlEvent e) { 284 e.childID = ACC.CHILDID_SELF; 285 } 286 287 public void getLocation(AccessibleControlEvent e) { 288 Rectangle rect = getDisplay().map(getParent(), null, getBounds()); 289 e.x = rect.x; 290 e.y = rect.y; 291 e.width = rect.width; 292 e.height = rect.height; 293 } 294 295 public void getChildCount(AccessibleControlEvent e) { 296 e.detail = 0; 297 } 298 299 public void getRole(AccessibleControlEvent e) { 300 e.detail = ACC.ROLE_LABEL; 301 } 302 303 public void getState(AccessibleControlEvent e) { 304 e.detail = ACC.STATE_READONLY; 305 } 306 }); 307 } 308 void onDispose(DisposeEvent event) { 309 gradientColors = null; 310 gradientPercents = null; 311 backgroundImage = null; 312 text = null; 313 image = null; 314 appToolTipText = null; 315 } 316 void onMnemonic(TraverseEvent event) { 317 char mnemonic = _findMnemonic(text); 318 if (mnemonic == '\0') return; 319 if (Character.toLowerCase(event.character) != mnemonic) return; 320 Composite control = this.getParent(); 321 while (control != null) { 322 Control [] children = control.getChildren(); 323 int index = 0; 324 while (index < children.length) { 325 if (children [index] == this) break; 326 index++; 327 } 328 index++; 329 if (index < children.length) { 330 if (children [index].setFocus ()) { 331 event.doit = true; 332 event.detail = SWT.TRAVERSE_NONE; 333 } 334 } 335 control = control.getParent(); 336 } 337 } 338 339 void onPaint(PaintEvent event) { 340 Rectangle rect = getClientArea(); 341 if (rect.width == 0 || rect.height == 0) return; 342 343 boolean shortenText = false; 344 String t = text; 345 Image img = image; 346 int availableWidth = Math.max(0, rect.width - 2*hIndent); 347 Point extent = getTotalSize(img, t); 348 if (extent.x > availableWidth) { 349 img = null; 350 extent = getTotalSize(img, t); 351 if (extent.x > availableWidth) { 352 shortenText = true; 353 } 354 } 355 356 GC gc = event.gc; 357 String [] lines = text == null ? null : splitString(text); 358 359 if (shortenText) { 361 extent.x = 0; 362 for(int i = 0; i < lines.length; i++) { 363 Point e = gc.textExtent(lines[i], DRAW_FLAGS); 364 if (e.x > availableWidth) { 365 lines[i] = shortenText(gc, lines[i], availableWidth); 366 extent.x = Math.max(extent.x, getTotalSize(null, lines[i]).x); 367 } else { 368 extent.x = Math.max(extent.x, e.x); 369 } 370 } 371 if (appToolTipText == null) { 372 super.setToolTipText(text); 373 } 374 } else { 375 super.setToolTipText(appToolTipText); 376 } 377 378 int x = rect.x + hIndent; 380 if (align == SWT.CENTER) { 381 x = (rect.width - extent.x)/2; 382 } 383 if (align == SWT.RIGHT) { 384 x = rect.width - hIndent - extent.x; 385 } 386 387 try { 389 if (backgroundImage != null) { 390 Rectangle imageRect = backgroundImage.getBounds(); 392 gc.setBackground(getBackground()); 394 gc.fillRectangle(rect); 395 int xPos = 0; 396 while (xPos < rect.width) { 397 int yPos = 0; 398 while (yPos < rect.height) { 399 gc.drawImage(backgroundImage, xPos, yPos); 400 yPos += imageRect.height; 401 } 402 xPos += imageRect.width; 403 } 404 } else if (gradientColors != null) { 405 final Color oldBackground = gc.getBackground(); 407 if (gradientColors.length == 1) { 408 if (gradientColors[0] != null) gc.setBackground(gradientColors[0]); 409 gc.fillRectangle(0, 0, rect.width, rect.height); 410 } else { 411 final Color oldForeground = gc.getForeground(); 412 Color lastColor = gradientColors[0]; 413 if (lastColor == null) lastColor = oldBackground; 414 int pos = 0; 415 for (int i = 0; i < gradientPercents.length; ++i) { 416 gc.setForeground(lastColor); 417 lastColor = gradientColors[i + 1]; 418 if (lastColor == null) lastColor = oldBackground; 419 gc.setBackground(lastColor); 420 if (gradientVertical) { 421 final int gradientHeight = (gradientPercents[i] * rect.height / 100) - pos; 422 gc.fillGradientRectangle(0, pos, rect.width, gradientHeight, true); 423 pos += gradientHeight; 424 } else { 425 final int gradientWidth = (gradientPercents[i] * rect.width / 100) - pos; 426 gc.fillGradientRectangle(pos, 0, gradientWidth, rect.height, false); 427 pos += gradientWidth; 428 } 429 } 430 if (gradientVertical && pos < rect.height) { 431 gc.setBackground(getBackground()); 432 gc.fillRectangle(0, pos, rect.width, rect.height - pos); 433 } 434 if (!gradientVertical && pos < rect.width) { 435 gc.setBackground(getBackground()); 436 gc.fillRectangle(pos, 0, rect.width - pos, rect.height); 437 } 438 gc.setForeground(oldForeground); 439 } 440 gc.setBackground(oldBackground); 441 } else { 442 if (background != null || (getStyle() & SWT.DOUBLE_BUFFERED) == 0) { 443 gc.setBackground(getBackground()); 444 gc.fillRectangle(rect); 445 } 446 } 447 } catch (SWTException e) { 448 if ((getStyle() & SWT.DOUBLE_BUFFERED) == 0) { 449 gc.setBackground(getBackground()); 450 gc.fillRectangle(rect); 451 } 452 } 453 454 int style = getStyle(); 456 if ((style & SWT.SHADOW_IN) != 0 || (style & SWT.SHADOW_OUT) != 0) { 457 paintBorder(gc, rect); 458 } 459 460 if (img != null) { 462 Rectangle imageRect = img.getBounds(); 463 gc.drawImage(img, 0, 0, imageRect.width, imageRect.height, 464 x, (rect.height-imageRect.height)/2, imageRect.width, imageRect.height); 465 x += imageRect.width + GAP; 466 extent.x -= imageRect.width + GAP; 467 } 468 if (lines != null) { 470 int lineHeight = gc.getFontMetrics().getHeight(); 471 int textHeight = lines.length * lineHeight; 472 int lineY = Math.max(vIndent, rect.y + (rect.height - textHeight) / 2); 473 gc.setForeground(getForeground()); 474 for (int i = 0; i < lines.length; i++) { 475 int lineX = x; 476 if (lines.length > 1) { 477 if (align == SWT.CENTER) { 478 int lineWidth = gc.textExtent(lines[i], DRAW_FLAGS).x; 479 lineX = x + Math.max(0, (extent.x - lineWidth) / 2); 480 } 481 if (align == SWT.RIGHT) { 482 int lineWidth = gc.textExtent(lines[i], DRAW_FLAGS).x; 483 lineX = Math.max(x, rect.x + rect.width - hIndent - lineWidth); 484 } 485 } 486 gc.drawText(lines[i], lineX, lineY, DRAW_FLAGS); 487 lineY += lineHeight; 488 } 489 } 490 } 491 494 private void paintBorder(GC gc, Rectangle r) { 495 Display disp= getDisplay(); 496 497 Color c1 = null; 498 Color c2 = null; 499 500 int style = getStyle(); 501 if ((style & SWT.SHADOW_IN) != 0) { 502 c1 = disp.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW); 503 c2 = disp.getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW); 504 } 505 if ((style & SWT.SHADOW_OUT) != 0) { 506 c1 = disp.getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW); 507 c2 = disp.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW); 508 } 509 510 if (c1 != null && c2 != null) { 511 gc.setLineWidth(1); 512 drawBevelRect(gc, r.x, r.y, r.width-1, r.height-1, c1, c2); 513 } 514 } 515 527 public void setAlignment(int align) { 528 checkWidget(); 529 if (align != SWT.LEFT && align != SWT.RIGHT && align != SWT.CENTER) { 530 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 531 } 532 if (this.align != align) { 533 this.align = align; 534 redraw(); 535 } 536 } 537 538 public void setBackground (Color color) { 539 super.setBackground (color); 540 if (backgroundImage == null && 542 gradientColors == null && 543 gradientPercents == null) { 544 if (color == null) { 545 if (background == null) return; 546 } else { 547 if (color.equals(background)) return; 548 } 549 } 550 background = color; 551 backgroundImage = null; 552 gradientColors = null; 553 gradientPercents = null; 554 redraw (); 555 } 556 557 584 public void setBackground(Color[] colors, int[] percents) { 585 setBackground(colors, percents, false); 586 } 587 615 public void setBackground(Color[] colors, int[] percents, boolean vertical) { 616 checkWidget(); 617 if (colors != null) { 618 if (percents == null || percents.length != colors.length - 1) { 619 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 620 } 621 if (getDisplay().getDepth() < 15) { 622 colors = new Color[] {colors[colors.length - 1]}; 624 percents = new int[] { }; 625 } 626 for (int i = 0; i < percents.length; i++) { 627 if (percents[i] < 0 || percents[i] > 100) { 628 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 629 } 630 if (i > 0 && percents[i] < percents[i-1]) { 631 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 632 } 633 } 634 } 635 636 final Color background = getBackground(); 638 if (backgroundImage == null) { 639 if ((gradientColors != null) && (colors != null) && 640 (gradientColors.length == colors.length)) { 641 boolean same = false; 642 for (int i = 0; i < gradientColors.length; i++) { 643 same = (gradientColors[i] == colors[i]) || 644 ((gradientColors[i] == null) && (colors[i] == background)) || 645 ((gradientColors[i] == background) && (colors[i] == null)); 646 if (!same) break; 647 } 648 if (same) { 649 for (int i = 0; i < gradientPercents.length; i++) { 650 same = gradientPercents[i] == percents[i]; 651 if (!same) break; 652 } 653 } 654 if (same && this.gradientVertical == vertical) return; 655 } 656 } else { 657 backgroundImage = null; 658 } 659 if (colors == null) { 661 gradientColors = null; 662 gradientPercents = null; 663 gradientVertical = false; 664 } else { 665 gradientColors = new Color[colors.length]; 666 for (int i = 0; i < colors.length; ++i) 667 gradientColors[i] = (colors[i] != null) ? colors[i] : background; 668 gradientPercents = new int[percents.length]; 669 for (int i = 0; i < percents.length; ++i) 670 gradientPercents[i] = percents[i]; 671 gradientVertical = vertical; 672 } 673 redraw(); 675 } 676 686 public void setBackground(Image image) { 687 checkWidget(); 688 if (image == backgroundImage) return; 689 if (image != null) { 690 gradientColors = null; 691 gradientPercents = null; 692 } 693 backgroundImage = image; 694 redraw(); 695 696 } 697 public void setFont(Font font) { 698 super.setFont(font); 699 redraw(); 700 } 701 712 public void setImage(Image image) { 713 checkWidget(); 714 if (image != this.image) { 715 this.image = image; 716 redraw(); 717 } 718 } 719 730 public void setText(String text) { 731 checkWidget(); 732 if (text == null) text = ""; if (! text.equals(this.text)) { 734 this.text = text; 735 redraw(); 736 } 737 } 738 public void setToolTipText (String string) { 739 super.setToolTipText (string); 740 appToolTipText = super.getToolTipText(); 741 } 742 753 protected String shortenText(GC gc, String t, int width) { 754 if (t == null) return null; 755 int w = gc.textExtent(ELLIPSIS, DRAW_FLAGS).x; 756 if (width<=w) return t; 757 int l = t.length(); 758 int max = l/2; 759 int min = 0; 760 int mid = (max+min)/2 - 1; 761 if (mid <= 0) return t; 762 while (min < mid && mid < max) { 763 String s1 = t.substring(0, mid); 764 String s2 = t.substring(l-mid, l); 765 int l1 = gc.textExtent(s1, DRAW_FLAGS).x; 766 int l2 = gc.textExtent(s2, DRAW_FLAGS).x; 767 if (l1+w+l2 > width) { 768 max = mid; 769 mid = (max+min)/2; 770 } else if (l1+w+l2 < width) { 771 min = mid; 772 mid = (max+min)/2; 773 } else { 774 min = max; 775 } 776 } 777 if (mid == 0) return t; 778 return t.substring(0, mid)+ELLIPSIS+t.substring(l-mid, l); 779 } 780 781 private String [] splitString(String text) { 782 String [] lines = new String [1]; 783 int start = 0, pos; 784 do { 785 pos = text.indexOf('\n', start); 786 if (pos == -1) { 787 lines[lines.length - 1] = text.substring(start); 788 } else { 789 boolean crlf = (pos > 0) && (text.charAt(pos - 1) == '\r'); 790 lines[lines.length - 1] = text.substring(start, pos - (crlf ? 1 : 0)); 791 start = pos + 1; 792 String [] newLines = new String [lines.length+1]; 793 System.arraycopy(lines, 0, newLines, 0, lines.length); 794 lines = newLines; 795 } 796 } while (pos != -1); 797 return lines; 798 } 799 } 800 | Popular Tags |