KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > presentations > r21 > widgets > CTabItem


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ui.internal.presentations.r21.widgets;
12
13 import org.eclipse.swt.SWT;
14 import org.eclipse.swt.SWTError;
15 import org.eclipse.swt.SWTException;
16 import org.eclipse.swt.graphics.Color;
17 import org.eclipse.swt.graphics.GC;
18 import org.eclipse.swt.graphics.Image;
19 import org.eclipse.swt.graphics.Rectangle;
20 import org.eclipse.swt.widgets.Control;
21 import org.eclipse.swt.widgets.Display;
22 import org.eclipse.swt.widgets.Item;
23 import org.eclipse.swt.widgets.Widget;
24
25 public class CTabItem extends Item {
26     CTabFolder parent;
27
28     int x, y, width, height = 0;
29
30     String JavaDoc toolTipText;
31
32     Control control; // the tab page
33

34     private Image disabledImage;
35
36     // internal constants
37
static final int LEFT_MARGIN = 4;
38
39     static final int RIGHT_MARGIN = 4;
40
41     static final int TOP_MARGIN = 3;
42
43     static final int BOTTOM_MARGIN = 3;
44
45     private static final int INTERNAL_SPACING = 2;
46
47     private static final String JavaDoc ellipsis = "..."; //$NON-NLS-1$
48

49     String JavaDoc shortenedText;
50
51     int shortenedTextWidth;
52
53     /**
54      * Constructs a new instance of this class given its parent
55      * (which must be a <code>CTabFolder</code>) and a style value
56      * describing its behavior and appearance. The item is added
57      * to the end of the items maintained by its parent.
58      * <p>
59      * The style value is either one of the style constants defined in
60      * class <code>SWT</code> which is applicable to instances of this
61      * class, or must be built by <em>bitwise OR</em>'ing together
62      * (that is, using the <code>int</code> "|" operator) two or more
63      * of those <code>SWT</code> style constants. The class description
64      * lists the style constants that are applicable to the class.
65      * Style bits are also inherited from superclasses.
66      * </p>
67      *
68      * @param parent a CTabFolder which will be the parent of the new instance (cannot be null)
69      * @param style the style of control to construct
70      *
71      * @exception IllegalArgumentException <ul>
72      * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
73      * </ul>
74      * @exception SWTException <ul>
75      * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
76      * </ul>
77      *
78      * @see SWT
79      * @see Widget#getStyle
80      */

81     public CTabItem(CTabFolder parent, int style) {
82         this(parent, style, parent.getItemCount());
83     }
84
85     /**
86      * Constructs a new instance of this class given its parent
87      * (which must be a <code>CTabFolder</code>), a style value
88      * describing its behavior and appearance, and the index
89      * at which to place it in the items maintained by its parent.
90      * <p>
91      * The style value is either one of the style constants defined in
92      * class <code>SWT</code> which is applicable to instances of this
93      * class, or must be built by <em>bitwise OR</em>'ing together
94      * (that is, using the <code>int</code> "|" operator) two or more
95      * of those <code>SWT</code> style constants. The class description
96      * lists the style constants that are applicable to the class.
97      * Style bits are also inherited from superclasses.
98      * </p>
99      *
100      * @param parent a CTabFolder which will be the parent of the new instance (cannot be null)
101      * @param style the style of control to construct
102      * @param index the index to store the receiver in its parent
103      *
104      * @exception IllegalArgumentException <ul>
105      * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
106      * </ul>
107      * @exception SWTException <ul>
108      * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
109      * </ul>
110      *
111      * @see SWT
112      * @see Widget#getStyle
113      */

114     public CTabItem(CTabFolder parent, int style, int index) {
115         super(parent, checkStyle(style));
116         parent.createItem(this, index);
117     }
118
119     private static int checkStyle(int style) {
120         return SWT.NONE;
121     }
122
123     public void dispose() {
124         if (isDisposed()) {
125             return;
126         }
127         parent.destroyItem(this);
128         super.dispose();
129         parent = null;
130         control = null;
131         toolTipText = null;
132     }
133
134     /**
135      * Returns a rectangle describing the receiver's size and location
136      * relative to its parent.
137      *
138      * @return the receiver's bounding column rectangle
139      *
140      * @exception SWTException <ul>
141      * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
142      * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
143      * </ul>
144      */

145     public Rectangle getBounds() {
146         //checkWidget();
147
return new Rectangle(x, y, width, height);
148     }
149
150     /**
151      * Gets the control that is displayed in the content are of the tab item.
152      *
153      * @return the control
154      *
155      * @exception SWTError(ERROR_THREAD_INVALID_ACCESS)
156      * when called from the wrong thread
157      * @exception SWTError(ERROR_WIDGET_DISPOSED)
158      * when the widget has been disposed
159      */

160     public Control getControl() {
161         checkWidget();
162         return control;
163     }
164
165     public Display getDisplay() {
166         if (parent == null) {
167             SWT.error(SWT.ERROR_WIDGET_DISPOSED);
168         }
169         return parent.getDisplay();
170     }
171
172     /**
173      * Get the image displayed in the tab if the tab is disabled.
174      *
175      * @return the disabled image or null
176      */

177     public Image getDisabledImage() {
178         //checkWidget();
179
return disabledImage;
180     }
181
182     /**
183      * Returns the receiver's parent, which must be a <code>CTabFolder</code>.
184      *
185      * @return the receiver's parent
186      */

187     public CTabFolder getParent() {
188         //checkWidget();
189
return parent;
190     }
191
192     /**
193      * Returns the receiver's tool tip text, or null if it has
194      * not been set.
195      *
196      * @return the receiver's tool tip text
197      *
198      * @exception SWTException <ul>
199      * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
200      * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
201      * </ul>
202      */

203     public String JavaDoc getToolTipText() {
204         checkWidget();
205         return toolTipText;
206     }
207
208     /**
209      * Paint the receiver.
210      */

211     void onPaint(GC gc, boolean isSelected) {
212
213         if (width == 0 || height == 0) {
214             return;
215         }
216
217         Display display = getDisplay();
218         Color highlightShadow = display
219                 .getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW);
220         Color normalShadow = display
221                 .getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
222
223         int index = parent.indexOf(this);
224
225         if (isSelected) {
226
227             Rectangle bounds = null;
228             if (!parent.onBottom) {
229                 if (index == parent.topTabIndex) {
230                     bounds = new Rectangle(x + 1, y + 1, width - 2, height - 1);
231                 } else {
232                     bounds = new Rectangle(x + 2, y + 1, width - 3, height - 1);
233                 }
234             } else {
235                 if (index == parent.topTabIndex) {
236                     bounds = new Rectangle(x + 1, y + 1, width - 2, height - 2);
237                 } else {
238                     bounds = new Rectangle(x + 2, y + 1, width - 3, height - 2);
239                 }
240             }
241             if (parent.backgroundImage != null) {
242                 // draw a background image behind the text
243
Rectangle imageRect = parent.backgroundImage.getBounds();
244                 gc.drawImage(parent.backgroundImage, 0, 0, imageRect.width,
245                         imageRect.height, bounds.x, bounds.y, bounds.width,
246                         bounds.height);
247             } else if (parent.gradientColors != null) {
248                 // draw a gradient behind the text
249
Color oldBackground = gc.getBackground();
250                 if (parent.gradientColors.length == 1) {
251                     if (parent.gradientColors[0] != null) {
252                         gc.setBackground(parent.gradientColors[0]);
253                     }
254                     gc.fillRectangle(bounds.x, bounds.y, bounds.width,
255                             bounds.height);
256                 } else {
257                     Color oldForeground = gc.getForeground();
258                     Color lastColor = parent.gradientColors[0];
259                     if (lastColor == null) {
260                         lastColor = oldBackground;
261                     }
262                     for (int i = 0, pos = 0; i < parent.gradientPercents.length; ++i) {
263                         gc.setForeground(lastColor);
264                         lastColor = parent.gradientColors[i + 1];
265                         if (lastColor == null) {
266                             lastColor = oldBackground;
267                         }
268                         gc.setBackground(lastColor);
269                         int gradientWidth = (parent.gradientPercents[i]
270                                 * bounds.width / 100)
271                                 - pos;
272                         gc.fillGradientRectangle(bounds.x + pos, bounds.y,
273                                 gradientWidth, bounds.height, false);
274                         pos += gradientWidth;
275                     }
276                     gc.setForeground(oldForeground);
277                 }
278                 gc.setBackground(oldBackground);
279             }
280
281             // draw tab lines
282
if (!parent.onBottom) {
283                 gc.setForeground(normalShadow);
284                 if (index != parent.topTabIndex) {
285                     gc.drawLine(x + 1, y, x + 1, y);
286                     gc.drawLine(x, y + 1, x, y + height - 2);
287                     gc.drawLine(x, y + height - 1, x, y + height - 1);
288                 }
289                 gc.drawLine(x + width - 1, y, x + width - 1, y);
290                 gc.drawLine(x + width, y + 1, x + width, y + height - 2);
291                 gc.drawLine(x + width, y + height - 1, x + width, y + height
292                         - 1);
293
294                 gc.setForeground(highlightShadow);
295                 if (index != parent.topTabIndex) {
296                     gc.drawLine(x + 2, y, x + 2, y);
297                     gc.drawLine(x + 1, y + 1, x + 1, y + height - 2);
298                     gc.drawLine(x + 1, y + height - 1, x + 1, y + height - 1);
299                 } else {
300                     gc.drawLine(x, y, x, y + height - 1);
301                 }
302
303                 gc.drawLine(x + width - 2, y, x + width - 2, y);
304                 gc
305                         .drawLine(x + width - 1, y + 1, x + width - 1, y
306                                 + height - 2);
307                 gc.drawLine(x + width - 1, y + height - 1, x + width - 1, y
308                         + height - 1);
309
310                 // light line across top
311
if (index != parent.topTabIndex) {
312                     gc.drawLine(x + 3, y, x + width - 3, y);
313                 } else {
314                     gc.drawLine(x + 1, y, x + width - 3, y);
315                 }
316             } else {
317                 gc.setForeground(normalShadow);
318                 if (index != parent.topTabIndex) {
319                     gc.drawLine(x, y, x, y);
320                     gc.drawLine(x, y + 1, x, y + height - 2);
321                     gc.drawLine(x + 1, y + height - 1, x + 1, y + height - 1);
322                 }
323                 gc.drawLine(x + width, y, x + width, y);
324                 gc.drawLine(x + width, y + 1, x + width, y + height - 2);
325                 gc.drawLine(x + width - 1, y + height - 1, x + width - 1, y
326                         + height - 1);
327
328                 gc.setForeground(highlightShadow);
329                 if (index != parent.topTabIndex) {
330                     gc.drawLine(x + 1, y, x + 1, y);
331                     gc.drawLine(x + 1, y + 1, x + 1, y + height - 2);
332                     gc.drawLine(x + 2, y + height - 1, x + 2, y + height - 1);
333                 } else {
334                     gc.drawLine(x, y, x, y + height - 1);
335                 }
336
337                 gc.drawLine(x + width - 1, y, x + width - 1, y);
338                 gc
339                         .drawLine(x + width - 1, y + 1, x + width - 1, y
340                                 + height - 2);
341                 gc.drawLine(x + width - 2, y + height - 1, x + width - 2, y
342                         + height - 1);
343
344                 // light line across top and bottom
345
if (index != parent.topTabIndex) {
346                     gc.drawLine(x + 1, y, x + width - 2, y);
347                     gc.drawLine(x + 2, y + height - 1, x + width - 3, y
348                             + height - 1);
349                 } else {
350                     gc.drawLine(x + 1, y, x + width - 2, y);
351                     gc.drawLine(x + 1, y + height - 1, x + width - 3, y
352                             + height - 1);
353                 }
354             }
355             if (parent.isFocusControl()) {
356                 // draw a focus rectangle
357
int x1, y1, width1, height1;
358                 if (!parent.onBottom) {
359                     if (index == parent.topTabIndex) {
360                         x1 = x + 1;
361                         y1 = y + 1;
362                         width1 = width - 2;
363                         height1 = height - 1;
364                     } else {
365                         x1 = x + 2;
366                         y1 = y + 1;
367                         width1 = width - 3;
368                         height1 = height - 1;
369                     }
370                 } else {
371                     if (index == parent.topTabIndex) {
372                         x1 = x + 1;
373                         y1 = y + 1;
374                         width1 = width - 2;
375                         height1 = height - 2;
376                     } else {
377                         x1 = x + 2;
378                         y1 = y + 1;
379                         width1 = width - 3;
380                         height1 = height - 2;
381                     }
382                 }
383                 gc.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
384                 gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
385                 gc.drawFocus(x1, y1, width1, height1);
386             }
387         } else {
388             // draw tab lines for unselected items
389
gc.setForeground(normalShadow);
390             if (!parent.onBottom) {
391                 if (index != parent.topTabIndex
392                         && index != parent.getSelectionIndex() + 1) {
393                     gc.drawLine(x, y, x, y + (height / 2));
394                 }
395             } else {
396                 if (index != parent.topTabIndex
397                         && index != parent.getSelectionIndex() + 1) {
398                     gc.drawLine(x, y + (height / 2), x, y + height - 1);
399                 }
400             }
401
402         }
403
404         // draw Image
405
int xDraw = x + LEFT_MARGIN;
406
407         Image image = getImage();
408         if (!isSelected && image != null) {
409             Image temp = getDisabledImage();
410             if (temp != null) {
411                 image = temp;
412             }
413         }
414         if (image != null) {
415             Rectangle imageBounds = image.getBounds();
416             int imageX = xDraw;
417             int imageHeight = Math.min(height - BOTTOM_MARGIN - TOP_MARGIN,
418                     imageBounds.height);
419             int imageY = y + (height - imageHeight) / 2;
420             int imageWidth = imageBounds.width * imageHeight
421                     / imageBounds.height;
422             gc.drawImage(image, imageBounds.x, imageBounds.y,
423                     imageBounds.width, imageBounds.height, imageX, imageY,
424                     imageWidth, imageHeight);
425             xDraw += imageWidth + INTERNAL_SPACING;
426         }
427
428         // draw Text
429
int textWidth = x + width - xDraw - RIGHT_MARGIN;
430         if (isSelected && parent.showClose) {
431             textWidth = x + width - xDraw - parent.closeBar.getSize().x
432                     - RIGHT_MARGIN;
433         }
434         if (shortenedText == null || shortenedTextWidth != textWidth) {
435             shortenedText = shortenText(gc, getText(), textWidth);
436             shortenedTextWidth = textWidth;
437         }
438         String JavaDoc text = shortenedText;
439
440         if (isSelected && parent.selectionForeground != null) {
441             gc.setForeground(parent.selectionForeground);
442         } else {
443             gc.setForeground(parent.getForeground());
444         }
445         int textY = y + (height - gc.textExtent(text, SWT.DRAW_MNEMONIC).y) / 2;
446         gc.drawText(text, xDraw, textY, SWT.DRAW_TRANSPARENT
447                 | SWT.DRAW_MNEMONIC);
448
449         gc.setForeground(parent.getForeground());
450     }
451
452     private static String JavaDoc shortenText(GC gc, String JavaDoc text, int width) {
453         if (gc.textExtent(text, SWT.DRAW_MNEMONIC).x <= width) {
454             return text;
455         }
456
457         int ellipseWidth = gc.textExtent(ellipsis, SWT.DRAW_MNEMONIC).x;
458         int length = text.length();
459         int end = length - 1;
460         while (end > 0) {
461             text = text.substring(0, end);
462             int l1 = gc.textExtent(text, SWT.DRAW_MNEMONIC).x;
463             if (l1 + ellipseWidth <= width) {
464                 return text + ellipsis;
465             }
466             end--;
467         }
468         return text + ellipsis;
469     }
470
471     /**
472      * Answer the preferred height of the receiver for the GC.
473      */

474     int preferredHeight(GC gc) {
475         Image image = getImage();
476         int height = 0;
477         if (image != null) {
478             height = image.getBounds().height;
479         }
480         String JavaDoc text = getText();
481         height = Math.max(height, gc.textExtent(text, SWT.DRAW_MNEMONIC).y);
482         return height + TOP_MARGIN + BOTTOM_MARGIN;
483     }
484
485     /**
486      * Answer the preferred width of the receiver for the GC.
487      */

488     int preferredWidth(GC gc) {
489         int width = 0;
490         Image image = getImage();
491         if (image != null) {
492             width += image.getBounds().width;
493         }
494         String JavaDoc text = getText();
495         if (text != null) {
496             if (image != null) {
497                 width += INTERNAL_SPACING;
498             }
499             width += gc.textExtent(text, SWT.DRAW_MNEMONIC).x;
500         }
501         if (parent.showClose) {
502             width += INTERNAL_SPACING + preferredHeight(gc); // closebar will be square and will fill preferred height
503
}
504         return width + LEFT_MARGIN + RIGHT_MARGIN;
505     }
506
507     /**
508      * Sets the control that is used to fill the client area of
509      * the tab folder when the user selects the tab item.
510      * <p>
511      * @param control the new control (or null)
512      *
513      * @exception IllegalArgumentException <ul>
514      * <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li>
515      * <li>ERROR_INVALID_PARENT - if the control is not in the same widget tree</li>
516      * </ul>
517      * @exception SWTException <ul>
518      * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
519      * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
520      * </ul>
521      */

522     public void setControl(Control control) {
523         checkWidget();
524         if (control != null) {
525             if (control.isDisposed()) {
526                 SWT.error(SWT.ERROR_INVALID_ARGUMENT);
527             }
528             if (control.getParent() != parent) {
529                 SWT.error(SWT.ERROR_INVALID_PARENT);
530             }
531         }
532         if (this.control != null && !this.control.isDisposed()) {
533             this.control.setVisible(false);
534         }
535         this.control = control;
536         if (this.control != null) {
537             int index = parent.indexOf(this);
538             if (index == parent.getSelectionIndex()) {
539                 this.control.setBounds(parent.getClientArea());
540                 this.control.setVisible(true);
541             } else {
542                 this.control.setVisible(false);
543             }
544         }
545     }
546
547     public void setImage(Image image) {
548         checkWidget();
549         if (image != null && image.equals(getImage())) {
550             return;
551         }
552         super.setImage(image);
553         parent.resetTabSize(true);
554     }
555
556     /**
557      * Sets the image that is displayed if the tab item is disabled.
558      * Null will clear the image.
559      *
560      * @param image the image to be displayed when the item is disabled or null
561      *
562      * @exception SWTException <ul>
563      * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
564      * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
565      * </ul>
566      */

567     public void setDisabledImage(Image image) {
568         checkWidget();
569         if (image != null && image.equals(getDisabledImage())) {
570             return;
571         }
572         disabledImage = image;
573         parent.redraw();
574     }
575
576     /**
577      * Set the widget text.
578      * <p>
579      * This method sets the widget label. The label may include
580      * mnemonic characters but must not contain line delimiters.
581      *
582      * @param string the new label for the widget
583      *
584      * @exception IllegalArgumentException <ul>
585      * <li>ERROR_NULL_ARGUMENT - if the text is null</li>
586      * </ul>
587      * @exception SWTException <ul>
588      * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
589      * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
590      * </ul>
591      */

592     public void setText(String JavaDoc string) {
593         checkWidget();
594         if (string.equals(getText())) {
595             return;
596         }
597         super.setText(string);
598         shortenedText = null;
599         shortenedTextWidth = 0;
600         parent.resetTabSize(false);
601     }
602
603     /**
604      * Sets the receiver's tool tip text to the argument, which
605      * may be null indicating that no tool tip text should be shown.
606      *
607      * @param string the new tool tip text (or null)
608      *
609      * @exception SWTException <ul>
610      * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
611      * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
612      * </ul>
613      */

614     public void setToolTipText(String JavaDoc string) {
615         checkWidget();
616         toolTipText = string;
617     }
618 }
619
Popular Tags