Mercurial > projects > dwt2
annotate org.eclipse.swt.gtk.linux.x86/src/org/eclipse/swt/custom/CTabItem.d @ 113:fb3aa8075988
D2 support for the linux port.
author | Jacob Carlborg <doob@me.com> |
---|---|
date | Wed, 06 Apr 2011 21:57:23 +0200 |
parents | c01d033c633a |
children | 536e43f63c81 |
rev | line source |
---|---|
25 | 1 /******************************************************************************* |
2 * Copyright (c) 2000, 2008 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 * Port to the D programming language: | |
11 * Frank Benoit <benoit@tionex.de> | |
12 *******************************************************************************/ | |
13 module org.eclipse.swt.custom.CTabItem; | |
14 | |
15 import java.lang.all; | |
16 | |
17 | |
18 | |
19 import org.eclipse.swt.SWT; | |
20 import org.eclipse.swt.SWTException; | |
21 import org.eclipse.swt.graphics.Color; | |
22 import org.eclipse.swt.graphics.Font; | |
23 import org.eclipse.swt.graphics.GC; | |
24 import org.eclipse.swt.graphics.Image; | |
25 import org.eclipse.swt.graphics.Point; | |
26 import org.eclipse.swt.graphics.RGB; | |
27 import org.eclipse.swt.graphics.Rectangle; | |
28 import org.eclipse.swt.graphics.TextLayout; | |
29 import org.eclipse.swt.widgets.Control; | |
30 import org.eclipse.swt.widgets.Display; | |
31 import org.eclipse.swt.widgets.Item; | |
32 import org.eclipse.swt.widgets.Widget; | |
33 import org.eclipse.swt.custom.CTabFolder; | |
34 | |
113 | 35 |
36 version (Tango) | |
37 import tango.text.convert.Utf; | |
38 | |
39 else | |
40 { | |
41 import std.conv; | |
42 | |
43 alias to!(string) toString; | |
44 alias to!(dstring) toString32; | |
45 } | |
46 | |
25 | 47 /** |
48 * Instances of this class represent a selectable user interface object | |
49 * that represent a page in a notebook widget. | |
50 * | |
51 * <dl> | |
52 * <dt><b>Styles:</b></dt> | |
53 * <dd>SWT.CLOSE</dd> | |
54 * <dt><b>Events:</b></dt> | |
55 * <dd>(none)</dd> | |
56 * </dl> | |
57 * <p> | |
58 * IMPORTANT: This class is <em>not</em> intended to be subclassed. | |
59 * </p> | |
60 * | |
61 * @see <a href="http://www.eclipse.org/swt/snippets/#ctabfolder">CTabFolder, CTabItem snippets</a> | |
62 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> | |
63 */ | |
64 public class CTabItem : Item { | |
65 CTabFolder parent; | |
66 int x,y,width,height = 0; | |
67 Control control; // the tab page | |
68 | |
69 String toolTipText; | |
70 String shortenedText; | |
71 int shortenedTextWidth; | |
72 | |
73 // Appearance | |
74 Font font; | |
75 Image disabledImage; | |
76 | |
77 Rectangle closeRect; | |
78 int closeImageState = CTabFolder.NONE; | |
79 bool showClose = false; | |
80 bool showing = false; | |
81 | |
82 // internal constants | |
49
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
83 static const int TOP_MARGIN = 2; |
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
84 static const int BOTTOM_MARGIN = 2; |
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
85 static const int LEFT_MARGIN = 4; |
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
86 static const int RIGHT_MARGIN = 4; |
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
87 static const int INTERNAL_SPACING = 4; |
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
88 static const int FLAGS = SWT.DRAW_TRANSPARENT | SWT.DRAW_MNEMONIC; |
7a2dd761a8b2
more work until dmd 2.026 linux segfaults.
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
89 static const String ELLIPSIS = "..."; //$NON-NLS-1$ // could use the ellipsis glyph on some platforms "\u2026" |
25 | 90 |
91 /** | |
92 * Constructs a new instance of this class given its parent | |
93 * (which must be a <code>CTabFolder</code>) and a style value | |
94 * describing its behavior and appearance. The item is added | |
95 * to the end of the items maintained by its parent. | |
96 * <p> | |
97 * The style value is either one of the style constants defined in | |
98 * class <code>SWT</code> which is applicable to instances of this | |
99 * class, or must be built by <em>bitwise OR</em>'ing together | |
100 * (that is, using the <code>int</code> "|" operator) two or more | |
101 * of those <code>SWT</code> style constants. The class description | |
102 * lists the style constants that are applicable to the class. | |
103 * Style bits are also inherited from superclasses. | |
104 * </p> | |
105 * | |
106 * @param parent a CTabFolder which will be the parent of the new instance (cannot be null) | |
107 * @param style the style of control to construct | |
108 * | |
109 * @exception IllegalArgumentException <ul> | |
110 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
111 * </ul> | |
112 * @exception SWTException <ul> | |
113 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | |
114 * </ul> | |
115 * | |
116 * @see SWT | |
117 * @see Widget#getStyle() | |
118 */ | |
119 public this (CTabFolder parent, int style) { | |
120 this(parent, style, parent.getItemCount()); | |
121 } | |
122 /** | |
123 * Constructs a new instance of this class given its parent | |
124 * (which must be a <code>CTabFolder</code>), a style value | |
125 * describing its behavior and appearance, and the index | |
126 * at which to place it in the items maintained by its parent. | |
127 * <p> | |
128 * The style value is either one of the style constants defined in | |
129 * class <code>SWT</code> which is applicable to instances of this | |
130 * class, or must be built by <em>bitwise OR</em>'ing together | |
131 * (that is, using the <code>int</code> "|" operator) two or more | |
132 * of those <code>SWT</code> style constants. The class description | |
133 * lists the style constants that are applicable to the class. | |
134 * Style bits are also inherited from superclasses. | |
135 * </p> | |
136 * | |
137 * @param parent a CTabFolder which will be the parent of the new instance (cannot be null) | |
138 * @param style the style of control to construct | |
139 * @param index the zero-relative index to store the receiver in its parent | |
140 * | |
141 * @exception IllegalArgumentException <ul> | |
142 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
143 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li> | |
144 * </ul> | |
145 * @exception SWTException <ul> | |
146 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | |
147 * </ul> | |
148 * | |
149 * @see SWT | |
150 * @see Widget#getStyle() | |
151 */ | |
152 public this (CTabFolder parent, int style, int index) { | |
153 closeRect = new Rectangle(0, 0, 0, 0); | |
154 super (parent, style); | |
155 showClose = (style & SWT.CLOSE) !is 0; | |
156 parent.createItem (this, index); | |
157 } | |
158 | |
159 /* | |
160 * Return whether to use ellipses or just truncate labels | |
161 */ | |
162 bool useEllipses() { | |
163 return parent.simple; | |
164 } | |
165 | |
166 String shortenText(GC gc, String text, int width) { | |
167 return useEllipses() | |
168 ? shortenText(gc, text, width, ELLIPSIS) | |
169 : shortenText(gc, text, width, ""); //$NON-NLS-1$ | |
170 } | |
171 | |
172 String shortenText(GC gc, String text, int width, String ellipses) { | |
173 if (gc.textExtent(text, FLAGS).x <= width) return text; | |
174 int ellipseWidth = gc.textExtent(ellipses, FLAGS).x; | |
175 int length = text.length; | |
176 TextLayout layout = new TextLayout(getDisplay()); | |
177 layout.setText(text); | |
178 int end = layout.getPreviousOffset(length, SWT.MOVEMENT_CLUSTER); | |
179 while (end > 0) { | |
180 text = text[ 0 .. end ]; | |
181 int l = gc.textExtent(text, FLAGS).x; | |
182 if (l + ellipseWidth <= width) { | |
183 break; | |
184 } | |
185 end = layout.getPreviousOffset(end, SWT.MOVEMENT_CLUSTER); | |
186 } | |
187 layout.dispose(); | |
113 | 188 return end is 0 ? .toString(toString32(text)[0 .. 1]) : text ~ ellipses; |
25 | 189 } |
190 | |
191 public override void dispose() { | |
192 if (isDisposed ()) return; | |
193 //if (!isValidThread ()) error (SWT.ERROR_THREAD_INVALID_ACCESS); | |
194 parent.destroyItem(this); | |
195 super.dispose(); | |
196 parent = null; | |
197 control = null; | |
198 toolTipText = null; | |
199 shortenedText = null; | |
200 font = null; | |
201 } | |
202 void drawClose(GC gc) { | |
203 if (closeRect.width is 0 || closeRect.height is 0) return; | |
204 Display display = getDisplay(); | |
205 | |
206 // draw X 9x9 | |
207 int indent = Math.max(1, (CTabFolder.BUTTON_SIZE-9)/2); | |
208 int x = closeRect.x + indent; | |
209 int y = closeRect.y + indent; | |
210 y += parent.onBottom ? -1 : 1; | |
211 | |
212 Color closeBorder = display.getSystemColor(CTabFolder.BUTTON_BORDER); | |
213 switch (closeImageState) { | |
214 case CTabFolder.NORMAL: { | |
215 int[] shape = [x,y, x+2,y, x+4,y+2, x+5,y+2, x+7,y, x+9,y, | |
216 x+9,y+2, x+7,y+4, x+7,y+5, x+9,y+7, x+9,y+9, | |
217 x+7,y+9, x+5,y+7, x+4,y+7, x+2,y+9, x,y+9, | |
218 x,y+7, x+2,y+5, x+2,y+4, x,y+2]; | |
219 gc.setBackground(display.getSystemColor(CTabFolder.BUTTON_FILL)); | |
220 gc.fillPolygon(shape); | |
221 gc.setForeground(closeBorder); | |
222 gc.drawPolygon(shape); | |
223 break; | |
224 } | |
225 case CTabFolder.HOT: { | |
226 int[] shape = [x,y, x+2,y, x+4,y+2, x+5,y+2, x+7,y, x+9,y, | |
227 x+9,y+2, x+7,y+4, x+7,y+5, x+9,y+7, x+9,y+9, | |
228 x+7,y+9, x+5,y+7, x+4,y+7, x+2,y+9, x,y+9, | |
229 x,y+7, x+2,y+5, x+2,y+4, x,y+2]; | |
51 | 230 Color fill = new Color(display, cast(RGB)CTabFolder.CLOSE_FILL); |
25 | 231 gc.setBackground(fill); |
232 gc.fillPolygon(shape); | |
233 fill.dispose(); | |
234 gc.setForeground(closeBorder); | |
235 gc.drawPolygon(shape); | |
236 break; | |
237 } | |
238 case CTabFolder.SELECTED: { | |
239 int[] shape = [x+1,y+1, x+3,y+1, x+5,y+3, x+6,y+3, x+8,y+1, x+10,y+1, | |
240 x+10,y+3, x+8,y+5, x+8,y+6, x+10,y+8, x+10,y+10, | |
241 x+8,y+10, x+6,y+8, x+5,y+8, x+3,y+10, x+1,y+10, | |
242 x+1,y+8, x+3,y+6, x+3,y+5, x+1,y+3]; | |
51 | 243 Color fill = new Color(display, cast(RGB)CTabFolder.CLOSE_FILL); |
25 | 244 gc.setBackground(fill); |
245 gc.fillPolygon(shape); | |
246 fill.dispose(); | |
247 gc.setForeground(closeBorder); | |
248 gc.drawPolygon(shape); | |
249 break; | |
250 } | |
251 case CTabFolder.NONE: { | |
252 int[] shape = [x,y, x+10,y, x+10,y+10, x,y+10]; | |
253 if (parent.gradientColors !is null && !parent.gradientVertical) { | |
254 parent.drawBackground(gc, shape, false); | |
255 } else { | |
256 Color defaultBackground = parent.getBackground(); | |
257 Image image = parent.bgImage; | |
258 Color[] colors = parent.gradientColors; | |
259 int[] percents = parent.gradientPercents; | |
260 bool vertical = parent.gradientVertical; | |
261 parent.drawBackground(gc, shape, x, y, 10, 10, defaultBackground, image, colors, percents, vertical); | |
262 } | |
263 break; | |
264 } | |
265 default: | |
266 } | |
267 } | |
268 void drawSelected(GC gc ) { | |
269 Point size = parent.getSize(); | |
270 int rightEdge = Math.min (x + width, parent.getRightItemEdge()); | |
271 | |
272 // Draw selection border across all tabs | |
273 int xx = parent.borderLeft; | |
274 int yy = parent.onBottom ? size.y - parent.borderBottom - parent.tabHeight - parent.highlight_header : parent.borderTop + parent.tabHeight + 1; | |
275 int ww = size.x - parent.borderLeft - parent.borderRight; | |
276 int hh = parent.highlight_header - 1; | |
277 int[] shape = [xx,yy, xx+ww,yy, xx+ww,yy+hh, xx,yy+hh]; | |
278 if (parent.selectionGradientColors !is null && !parent.selectionGradientVertical) { | |
279 parent.drawBackground(gc, shape, true); | |
280 } else { | |
281 gc.setBackground(parent.selectionBackground); | |
282 gc.fillRectangle(xx, yy, ww, hh); | |
283 } | |
284 | |
285 if (parent.single) { | |
286 if (!showing) return; | |
287 } else { | |
288 // if selected tab scrolled out of view or partially out of view | |
289 // just draw bottom line | |
290 if (!showing){ | |
291 int x1 = Math.max(0, parent.borderLeft - 1); | |
292 int y1 = (parent.onBottom) ? y - 1 : y + height; | |
293 int x2 = size.x - parent.borderRight; | |
294 gc.setForeground(CTabFolder.borderColor); | |
295 gc.drawLine(x1, y1, x2, y1); | |
296 return; | |
297 } | |
298 | |
299 // draw selected tab background and outline | |
300 shape = null; | |
301 if (this.parent.onBottom) { | |
302 int[] left = parent.simple ? CTabFolder.SIMPLE_BOTTOM_LEFT_CORNER : CTabFolder.BOTTOM_LEFT_CORNER; | |
51 | 303 int[] right = parent.simple ? cast(int[])CTabFolder.SIMPLE_BOTTOM_RIGHT_CORNER : parent.curve; |
25 | 304 if (parent.borderLeft is 0 && parent.indexOf(this) is parent.firstIndex) { |
305 left = [x, y+height]; | |
306 } | |
307 shape = new int[left.length+right.length+8]; | |
308 int index = 0; | |
309 shape[index++] = x; // first point repeated here because below we reuse shape to draw outline | |
310 shape[index++] = y - 1; | |
311 shape[index++] = x; | |
312 shape[index++] = y - 1; | |
313 for (int i = 0; i < left.length/2; i++) { | |
314 shape[index++] = x + left[2*i]; | |
315 shape[index++] = y + height + left[2*i+1] - 1; | |
316 } | |
317 for (int i = 0; i < right.length/2; i++) { | |
318 shape[index++] = parent.simple ? rightEdge - 1 + right[2*i] : rightEdge - parent.curveIndent + right[2*i]; | |
319 shape[index++] = parent.simple ? y + height + right[2*i+1] - 1 : y + right[2*i+1] - 2; | |
320 } | |
321 shape[index++] = parent.simple ? rightEdge - 1 : rightEdge + parent.curveWidth - parent.curveIndent; | |
322 shape[index++] = y - 1; | |
323 shape[index++] = parent.simple ? rightEdge - 1 : rightEdge + parent.curveWidth - parent.curveIndent; | |
324 shape[index++] = y - 1; | |
325 } else { | |
326 int[] left = parent.simple ? CTabFolder.SIMPLE_TOP_LEFT_CORNER : CTabFolder.TOP_LEFT_CORNER; | |
51 | 327 int[] right = parent.simple ? cast(int[])CTabFolder.SIMPLE_TOP_RIGHT_CORNER : parent.curve; |
25 | 328 if (parent.borderLeft is 0 && parent.indexOf(this) is parent.firstIndex) { |
329 left = [x, y]; | |
330 } | |
331 shape = new int[left.length+right.length+8]; | |
332 int index = 0; | |
333 shape[index++] = x; // first point repeated here because below we reuse shape to draw outline | |
334 shape[index++] = y + height + 1; | |
335 shape[index++] = x; | |
336 shape[index++] = y + height + 1; | |
337 for (int i = 0; i < left.length/2; i++) { | |
338 shape[index++] = x + left[2*i]; | |
339 shape[index++] = y + left[2*i+1]; | |
340 } | |
341 for (int i = 0; i < right.length/2; i++) { | |
342 shape[index++] = parent.simple ? rightEdge - 1 + right[2*i] : rightEdge - parent.curveIndent + right[2*i]; | |
343 shape[index++] = y + right[2*i+1]; | |
344 } | |
345 shape[index++] = parent.simple ? rightEdge - 1 : rightEdge + parent.curveWidth - parent.curveIndent; | |
346 shape[index++] = y + height + 1; | |
347 shape[index++] = parent.simple ? rightEdge - 1 : rightEdge + parent.curveWidth - parent.curveIndent; | |
348 shape[index++] = y + height + 1; | |
349 } | |
350 | |
351 Rectangle clipping = gc.getClipping(); | |
352 Rectangle bounds = getBounds(); | |
353 bounds.height += 1; | |
354 if (parent.onBottom) bounds.y -= 1; | |
355 bool tabInPaint = clipping.intersects(bounds); | |
356 | |
357 if (tabInPaint) { | |
358 // fill in tab background | |
359 if (parent.selectionGradientColors !is null && !parent.selectionGradientVertical) { | |
360 parent.drawBackground(gc, shape, true); | |
361 } else { | |
362 Color defaultBackground = parent.selectionBackground; | |
363 Image image = parent.selectionBgImage; | |
364 Color[] colors = parent.selectionGradientColors; | |
365 int[] percents = parent.selectionGradientPercents; | |
366 bool vertical = parent.selectionGradientVertical; | |
367 xx = x; | |
368 yy = parent.onBottom ? y -1 : y + 1; | |
369 ww = width; | |
370 hh = height; | |
371 if (!parent.single && !parent.simple) ww += parent.curveWidth - parent.curveIndent; | |
372 parent.drawBackground(gc, shape, xx, yy, ww, hh, defaultBackground, image, colors, percents, vertical); | |
373 } | |
374 } | |
375 | |
376 //Highlight MUST be drawn before the outline so that outline can cover it in the right spots (start of swoop) | |
377 //otherwise the curve looks jagged | |
378 drawHighlight(gc, rightEdge); | |
379 | |
380 // draw outline | |
381 shape[0] = Math.max(0, parent.borderLeft - 1); | |
382 if (parent.borderLeft is 0 && parent.indexOf(this) is parent.firstIndex) { | |
383 shape[1] = parent.onBottom ? y + height - 1 : y; | |
384 shape[5] = shape[3] = shape[1]; | |
385 } | |
386 shape[shape.length - 2] = size.x - parent.borderRight + 1; | |
387 for (int i = 0; i < shape.length/2; i++) { | |
388 if (shape[2*i + 1] is y + height + 1) shape[2*i + 1] -= 1; | |
389 } | |
390 RGB inside = parent.selectionBackground.getRGB(); | |
391 if (parent.selectionBgImage !is null || | |
392 (parent.selectionGradientColors !is null && parent.selectionGradientColors.length > 1)) { | |
393 inside = null; | |
394 } | |
395 RGB outside = parent.getBackground().getRGB(); | |
396 if (parent.bgImage !is null || | |
397 (parent.gradientColors !is null && parent.gradientColors.length > 1)) { | |
398 outside = null; | |
399 } | |
400 parent.antialias(shape, CTabFolder.borderColor.getRGB(), inside, outside, gc); | |
401 gc.setForeground(CTabFolder.borderColor); | |
402 gc.drawPolyline(shape); | |
403 | |
404 if (!tabInPaint) return; | |
405 } | |
406 | |
407 // draw Image | |
408 int xDraw = x + LEFT_MARGIN; | |
409 if (parent.single && (parent.showClose || showClose)) xDraw += CTabFolder.BUTTON_SIZE; | |
410 Image image = getImage(); | |
411 if (image !is null) { | |
412 Rectangle imageBounds = image.getBounds(); | |
413 // only draw image if it won't overlap with close button | |
414 int maxImageWidth = rightEdge - xDraw - RIGHT_MARGIN; | |
415 if (!parent.single && closeRect.width > 0) maxImageWidth -= closeRect.width + INTERNAL_SPACING; | |
416 if (imageBounds.width < maxImageWidth) { | |
417 int imageX = xDraw; | |
418 int imageY = y + (height - imageBounds.height) / 2; | |
419 imageY += parent.onBottom ? -1 : 1; | |
420 gc.drawImage(image, imageX, imageY); | |
421 xDraw += imageBounds.width + INTERNAL_SPACING; | |
422 } | |
423 } | |
424 | |
425 // draw Text | |
426 int textWidth = rightEdge - xDraw - RIGHT_MARGIN; | |
427 if (!parent.single && closeRect.width > 0) textWidth -= closeRect.width + INTERNAL_SPACING; | |
428 if (textWidth > 0) { | |
429 Font gcFont = gc.getFont(); | |
430 gc.setFont(font is null ? parent.getFont() : font); | |
431 | |
432 if (shortenedText is null || shortenedTextWidth !is textWidth) { | |
433 shortenedText = shortenText(gc, getText(), textWidth); | |
434 shortenedTextWidth = textWidth; | |
435 } | |
436 Point extent = gc.textExtent(shortenedText, FLAGS); | |
437 int textY = y + (height - extent.y) / 2; | |
438 textY += parent.onBottom ? -1 : 1; | |
439 | |
440 gc.setForeground(parent.selectionForeground); | |
441 gc.drawText(shortenedText, xDraw, textY, FLAGS); | |
442 gc.setFont(gcFont); | |
443 | |
444 // draw a Focus rectangle | |
445 if (parent.isFocusControl()) { | |
446 Display display = getDisplay(); | |
447 if (parent.simple || parent.single) { | |
448 gc.setBackground(display.getSystemColor(SWT.COLOR_BLACK)); | |
449 gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE)); | |
450 gc.drawFocus(xDraw-1, textY-1, extent.x+2, extent.y+2); | |
451 } else { | |
452 gc.setForeground(display.getSystemColor(CTabFolder.BUTTON_BORDER)); | |
453 gc.drawLine(xDraw, textY+extent.y+1, xDraw+extent.x+1, textY+extent.y+1); | |
454 } | |
455 } | |
456 } | |
457 if (parent.showClose || showClose) drawClose(gc); | |
458 } | |
459 | |
460 /* | |
461 * Draw a highlight effect along the left, top, and right edges of the tab. | |
462 * Only for curved tabs, on top. | |
463 * Do not draw if insufficient colors. | |
464 */ | |
465 void drawHighlight(GC gc, int rightEdge) { | |
466 //only draw for curvy tabs and only draw for top tabs | |
467 if(parent.simple || this.parent.onBottom) | |
468 return; | |
469 | |
470 if(parent.selectionHighlightGradientBegin is null) | |
471 return; | |
472 | |
473 Color[] gradients = parent.selectionHighlightGradientColorsCache; | |
474 if(gradients is null) | |
475 return; | |
476 int gradientsSize = gradients.length; | |
477 if(gradientsSize is 0) | |
478 return; //shouldn't happen but just to be tidy | |
479 | |
480 gc.setForeground(gradients[0]); | |
481 | |
482 //draw top horizontal line | |
483 gc.drawLine( | |
484 CTabFolder.TOP_LEFT_CORNER_HILITE[0] + x + 1, //rely on fact that first pair is top/right of curve | |
485 1 + y, | |
486 rightEdge - parent.curveIndent, | |
487 1 + y); | |
488 | |
489 int[] leftHighlightCurve = CTabFolder.TOP_LEFT_CORNER_HILITE; | |
490 | |
491 int d = parent.tabHeight - parent.topCurveHighlightEnd.length /2; | |
492 | |
493 int lastX = 0; | |
494 int lastY = 0; | |
495 int lastColorIndex = 0; | |
496 | |
497 //draw upper left curve highlight | |
498 for (int i = 0; i < leftHighlightCurve.length /2; i++) { | |
499 int rawX = leftHighlightCurve[i * 2]; | |
500 int rawY = leftHighlightCurve[i * 2 + 1]; | |
501 lastX = rawX + x; | |
502 lastY = rawY + y; | |
503 lastColorIndex = rawY - 1; | |
504 gc.setForeground(gradients[lastColorIndex]); | |
505 gc.drawPoint(lastX, lastY); | |
506 } | |
507 //draw left vertical line highlight | |
508 for(int i = lastColorIndex; i < gradientsSize; i++) { | |
509 gc.setForeground(gradients[i]); | |
510 gc.drawPoint(lastX, 1 + lastY++); | |
511 } | |
512 | |
513 int rightEdgeOffset = rightEdge - parent.curveIndent; | |
514 | |
515 //draw right swoop highlight up to diagonal portion | |
516 for (int i = 0; i < parent.topCurveHighlightStart.length /2; i++) { | |
517 int rawX = parent.topCurveHighlightStart[i * 2]; | |
518 int rawY = parent.topCurveHighlightStart[i * 2 + 1]; | |
519 lastX = rawX + rightEdgeOffset; | |
520 lastY = rawY + y; | |
521 lastColorIndex = rawY - 1; | |
522 if(lastColorIndex >= gradientsSize) | |
523 break; //can happen if tabs are unusually short and cut off the curve | |
524 gc.setForeground(gradients[lastColorIndex]); | |
525 gc.drawPoint(lastX, lastY); | |
526 } | |
527 //draw right diagonal line highlight | |
528 for(int i = lastColorIndex; i < lastColorIndex + d; i++) { | |
529 if(i >= gradientsSize) | |
530 break; //can happen if tabs are unusually short and cut off the curve | |
531 gc.setForeground(gradients[i]); | |
532 gc.drawPoint(1 + lastX++, 1 + lastY++); | |
533 } | |
534 | |
535 //draw right swoop highlight from diagonal portion to end | |
536 for (int i = 0; i < parent.topCurveHighlightEnd.length /2; i++) { | |
537 int rawX = parent.topCurveHighlightEnd[i * 2]; //d is already encoded in this value | |
538 int rawY = parent.topCurveHighlightEnd[i * 2 + 1]; //d already encoded | |
539 lastX = rawX + rightEdgeOffset; | |
540 lastY = rawY + y; | |
541 lastColorIndex = rawY - 1; | |
542 if(lastColorIndex >= gradientsSize) | |
543 break; //can happen if tabs are unusually short and cut off the curve | |
544 gc.setForeground(gradients[lastColorIndex]); | |
545 gc.drawPoint(lastX, lastY); | |
546 } | |
547 } | |
548 | |
549 /* | |
550 * Draw the unselected border for the receiver on the right. | |
551 * | |
552 * @param gc | |
553 */ | |
554 void drawRightUnselectedBorder(GC gc) { | |
555 | |
556 int[] shape = null; | |
557 int startX = x + width - 1; | |
558 | |
559 if (this.parent.onBottom) { | |
560 int[] right = parent.simple | |
561 ? CTabFolder.SIMPLE_UNSELECTED_INNER_CORNER | |
562 : CTabFolder.BOTTOM_RIGHT_CORNER; | |
563 | |
564 shape = new int[right.length + 2]; | |
565 int index = 0; | |
566 | |
567 for (int i = 0; i < right.length / 2; i++) { | |
568 shape[index++] = startX + right[2 * i]; | |
569 shape[index++] = y + height + right[2 * i + 1] - 1; | |
570 } | |
571 shape[index++] = startX; | |
572 shape[index++] = y - 1; | |
573 } else { | |
574 int[] right = parent.simple | |
575 ? CTabFolder.SIMPLE_UNSELECTED_INNER_CORNER | |
576 : CTabFolder.TOP_RIGHT_CORNER; | |
577 | |
578 shape = new int[right.length + 2]; | |
579 int index = 0; | |
580 | |
581 for (int i = 0; i < right.length / 2; i++) { | |
582 shape[index++] = startX + right[2 * i]; | |
583 shape[index++] = y + right[2 * i + 1]; | |
584 } | |
585 | |
586 shape[index++] = startX; | |
587 shape[index++] = y + height; | |
588 | |
589 } | |
590 | |
591 drawBorder(gc, shape); | |
592 | |
593 } | |
594 | |
595 /* | |
596 * Draw the border of the tab | |
597 * | |
598 * @param gc | |
599 * @param shape | |
600 */ | |
601 void drawBorder(GC gc, int[] shape) { | |
602 | |
603 gc.setForeground(CTabFolder.borderColor); | |
604 gc.drawPolyline(shape); | |
605 } | |
606 | |
607 /* | |
608 * Draw the unselected border for the receiver on the left. | |
609 * | |
610 * @param gc | |
611 */ | |
612 void drawLeftUnselectedBorder(GC gc) { | |
613 | |
614 int[] shape = null; | |
615 if (this.parent.onBottom) { | |
616 int[] left = parent.simple | |
617 ? CTabFolder.SIMPLE_UNSELECTED_INNER_CORNER | |
618 : CTabFolder.BOTTOM_LEFT_CORNER; | |
619 | |
620 shape = new int[left.length + 2]; | |
621 int index = 0; | |
622 shape[index++] = x; | |
623 shape[index++] = y - 1; | |
624 for (int i = 0; i < left.length / 2; i++) { | |
625 shape[index++] = x + left[2 * i]; | |
626 shape[index++] = y + height + left[2 * i + 1] - 1; | |
627 } | |
628 } else { | |
629 int[] left = parent.simple | |
630 ? CTabFolder.SIMPLE_UNSELECTED_INNER_CORNER | |
631 : CTabFolder.TOP_LEFT_CORNER; | |
632 | |
633 shape = new int[left.length + 2]; | |
634 int index = 0; | |
635 shape[index++] = x; | |
636 shape[index++] = y + height; | |
637 for (int i = 0; i < left.length / 2; i++) { | |
638 shape[index++] = x + left[2 * i]; | |
639 shape[index++] = y + left[2 * i + 1]; | |
640 } | |
641 | |
642 } | |
643 | |
644 drawBorder(gc, shape); | |
645 } | |
646 | |
647 void drawUnselected(GC gc) { | |
648 // Do not draw partial items | |
649 if (!showing) return; | |
650 | |
651 Rectangle clipping = gc.getClipping(); | |
652 Rectangle bounds = getBounds(); | |
653 if (!clipping.intersects(bounds)) return; | |
654 | |
655 // draw border | |
656 int index = parent.indexOf(this); | |
657 | |
658 if (index > 0 && index < parent.selectedIndex) | |
659 drawLeftUnselectedBorder(gc); | |
660 // If it is the last one then draw a line | |
661 if (index > parent.selectedIndex) | |
662 drawRightUnselectedBorder(gc); | |
663 | |
664 // draw Image | |
665 int xDraw = x + LEFT_MARGIN; | |
666 Image image = getImage(); | |
667 if (image !is null && parent.showUnselectedImage) { | |
668 Rectangle imageBounds = image.getBounds(); | |
669 // only draw image if it won't overlap with close button | |
670 int maxImageWidth = x + width - xDraw - RIGHT_MARGIN; | |
671 if (parent.showUnselectedClose && (parent.showClose || showClose)) { | |
672 maxImageWidth -= closeRect.width + INTERNAL_SPACING; | |
673 } | |
674 if (imageBounds.width < maxImageWidth) { | |
675 int imageX = xDraw; | |
676 int imageHeight = imageBounds.height; | |
677 int imageY = y + (height - imageHeight) / 2; | |
678 imageY += parent.onBottom ? -1 : 1; | |
679 int imageWidth = imageBounds.width * imageHeight / imageBounds.height; | |
680 gc.drawImage(image, | |
681 imageBounds.x, imageBounds.y, imageBounds.width, imageBounds.height, | |
682 imageX, imageY, imageWidth, imageHeight); | |
683 xDraw += imageWidth + INTERNAL_SPACING; | |
684 } | |
685 } | |
686 // draw Text | |
687 int textWidth = x + width - xDraw - RIGHT_MARGIN; | |
688 if (parent.showUnselectedClose && (parent.showClose || showClose)) { | |
689 textWidth -= closeRect.width + INTERNAL_SPACING; | |
690 } | |
691 if (textWidth > 0) { | |
692 Font gcFont = gc.getFont(); | |
693 gc.setFont(font is null ? parent.getFont() : font); | |
694 if (shortenedText is null || shortenedTextWidth !is textWidth) { | |
695 shortenedText = shortenText(gc, getText(), textWidth); | |
696 shortenedTextWidth = textWidth; | |
697 } | |
698 Point extent = gc.textExtent(shortenedText, FLAGS); | |
699 int textY = y + (height - extent.y) / 2; | |
700 textY += parent.onBottom ? -1 : 1; | |
701 gc.setForeground(parent.getForeground()); | |
702 gc.drawText(shortenedText, xDraw, textY, FLAGS); | |
703 gc.setFont(gcFont); | |
704 } | |
705 // draw close | |
706 if (parent.showUnselectedClose && (parent.showClose || showClose)) drawClose(gc); | |
707 } | |
708 /** | |
709 * Returns a rectangle describing the receiver's size and location | |
710 * relative to its parent. | |
711 * | |
712 * @return the receiver's bounding column rectangle | |
713 * | |
714 * @exception SWTException <ul> | |
715 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
716 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
717 * </ul> | |
718 */ | |
719 public Rectangle getBounds () { | |
720 //checkWidget(); | |
721 int w = width; | |
722 if (!parent.simple && !parent.single && parent.indexOf(this) is parent.selectedIndex) w += parent.curveWidth - parent.curveIndent; | |
723 return new Rectangle(x, y, w, height); | |
724 } | |
725 /** | |
726 * Gets the control that is displayed in the content area of the tab item. | |
727 * | |
728 * @return the control | |
729 * | |
730 * @exception SWTException <ul> | |
731 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
732 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
733 * </ul> | |
734 */ | |
735 public Control getControl () { | |
736 checkWidget(); | |
737 return control; | |
738 } | |
739 /** | |
740 * Get the image displayed in the tab if the tab is disabled. | |
741 * | |
742 * @return the disabled image or null | |
743 * | |
744 * @exception SWTException <ul> | |
745 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
746 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
747 * </ul> | |
748 * | |
749 * @deprecated the disabled image is not used | |
750 */ | |
751 public Image getDisabledImage(){ | |
752 checkWidget(); | |
753 return disabledImage; | |
754 } | |
755 /** | |
756 * Returns the font that the receiver will use to paint textual information. | |
757 * | |
758 * @return the receiver's font | |
759 * | |
760 * @exception SWTException <ul> | |
761 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
762 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
763 * </ul> | |
764 * | |
765 * @since 3.0 | |
766 */ | |
767 public Font getFont() { | |
768 checkWidget(); | |
769 if (font !is null) return font; | |
770 return parent.getFont(); | |
771 } | |
772 /** | |
773 * Returns the receiver's parent, which must be a <code>CTabFolder</code>. | |
774 * | |
775 * @return the receiver's parent | |
776 * | |
777 * @exception SWTException <ul> | |
778 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
779 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
780 * </ul> | |
781 */ | |
782 public CTabFolder getParent () { | |
783 //checkWidget(); | |
784 return parent; | |
785 } | |
786 /** | |
787 * Returns <code>true</code> to indicate that the receiver's close button should be shown. | |
788 * Otherwise return <code>false</code>. The initial value is defined by the style (SWT.CLOSE) | |
789 * that was used to create the receiver. | |
790 * | |
791 * @return <code>true</code> if the close button should be shown | |
792 * | |
793 * @exception SWTException <ul> | |
794 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
795 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
796 * </ul> | |
797 * | |
798 * @since 3.4 | |
799 */ | |
800 public bool getShowClose() { | |
801 checkWidget(); | |
802 return showClose; | |
803 } | |
804 /** | |
805 * Returns the receiver's tool tip text, or null if it has | |
806 * not been set. | |
807 * | |
808 * @return the receiver's tool tip text | |
809 * | |
810 * @exception SWTException <ul> | |
811 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
812 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
813 * </ul> | |
814 */ | |
815 public String getToolTipText () { | |
816 checkWidget(); | |
817 if (toolTipText is null && shortenedText !is null) { | |
818 String text = getText(); | |
819 if (shortenedText!=text) return text; | |
820 } | |
821 return toolTipText; | |
822 } | |
823 /** | |
824 * Returns <code>true</code> if the item will be rendered in the visible area of the CTabFolder. Returns false otherwise. | |
825 * | |
826 * @return <code>true</code> if the item will be rendered in the visible area of the CTabFolder. Returns false otherwise. | |
827 * | |
828 * @exception SWTException <ul> | |
829 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
830 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
831 * </ul> | |
832 * | |
833 * @since 3.0 | |
834 */ | |
835 public bool isShowing () { | |
836 checkWidget(); | |
837 return showing; | |
838 } | |
839 void onPaint(GC gc, bool isSelected) { | |
840 if (width is 0 || height is 0) return; | |
841 if (isSelected) { | |
842 drawSelected(gc); | |
843 } else { | |
844 drawUnselected(gc); | |
845 } | |
846 } | |
847 int preferredHeight(GC gc) { | |
848 Image image = getImage(); | |
849 int h = (image is null) ? 0 : image.getBounds().height; | |
850 String text = getText(); | |
851 if (font is null) { | |
852 h = Math.max(h, gc.textExtent(text, FLAGS).y); | |
853 } else { | |
854 Font gcFont = gc.getFont(); | |
855 gc.setFont(font); | |
856 h = Math.max(h, gc.textExtent(text, FLAGS).y); | |
857 gc.setFont(gcFont); | |
858 } | |
859 return h + TOP_MARGIN + BOTTOM_MARGIN; | |
860 } | |
861 int preferredWidth(GC gc, bool isSelected, bool minimum) { | |
862 // NOTE: preferred width does not include the "dead space" caused | |
863 // by the curve. | |
864 if (isDisposed()) return 0; | |
865 int w = 0; | |
866 Image image = getImage(); | |
867 if (image !is null && (isSelected || parent.showUnselectedImage)) { | |
868 w += image.getBounds().width; | |
869 } | |
870 String text = null; | |
871 if (minimum) { | |
872 int minChars = parent.minChars; | |
873 text = minChars is 0 ? null : getText(); | |
113 | 874 if (text !is null && toString32(text).length > minChars) { |
25 | 875 if (useEllipses()) { |
876 int end = minChars < ELLIPSIS.length + 1 ? minChars : minChars - ELLIPSIS.length; | |
113 | 877 text = .toString(toString32(text)[ 0 .. end ]); |
25 | 878 if (minChars > ELLIPSIS.length + 1) text ~= ELLIPSIS; |
879 } else { | |
880 int end = minChars; | |
113 | 881 text = .toString(toString32(text)[ 0 .. end ]); |
25 | 882 } |
883 } | |
884 } else { | |
885 text = getText(); | |
886 } | |
887 if (text !is null) { | |
888 if (w > 0) w += INTERNAL_SPACING; | |
889 if (font is null) { | |
890 w += gc.textExtent(text, FLAGS).x; | |
891 } else { | |
892 Font gcFont = gc.getFont(); | |
893 gc.setFont(font); | |
894 w += gc.textExtent(text, FLAGS).x; | |
895 gc.setFont(gcFont); | |
896 } | |
897 } | |
898 if (parent.showClose || showClose) { | |
899 if (isSelected || parent.showUnselectedClose) { | |
900 if (w > 0) w += INTERNAL_SPACING; | |
901 w += CTabFolder.BUTTON_SIZE; | |
902 } | |
903 } | |
904 return w + LEFT_MARGIN + RIGHT_MARGIN; | |
905 } | |
906 /** | |
907 * Sets the control that is used to fill the client area of | |
908 * the tab folder when the user selects the tab item. | |
909 * | |
910 * @param control the new control (or null) | |
911 * | |
912 * @exception IllegalArgumentException <ul> | |
913 * <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li> | |
914 * <li>ERROR_INVALID_PARENT - if the control is not in the same widget tree</li> | |
915 * </ul> | |
916 * @exception SWTException <ul> | |
917 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
918 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
919 * </ul> | |
920 */ | |
921 public void setControl (Control control) { | |
922 checkWidget(); | |
923 if (control !is null) { | |
924 if (control.isDisposed()) SWT.error (SWT.ERROR_INVALID_ARGUMENT); | |
925 if (control.getParent() !is parent) SWT.error (SWT.ERROR_INVALID_PARENT); | |
926 } | |
927 if (this.control !is null && !this.control.isDisposed()) { | |
928 this.control.setVisible(false); | |
929 } | |
930 this.control = control; | |
931 if (this.control !is null) { | |
932 int index = parent.indexOf (this); | |
933 if (index is parent.getSelectionIndex ()){ | |
934 this.control.setBounds(parent.getClientArea ()); | |
935 this.control.setVisible(true); | |
936 } else { | |
937 this.control.setVisible(false); | |
938 } | |
939 } | |
940 } | |
941 /** | |
942 * Sets the image that is displayed if the tab item is disabled. | |
943 * Null will clear the image. | |
944 * | |
945 * @param image the image to be displayed when the item is disabled or null | |
946 * | |
947 * @exception SWTException <ul> | |
948 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
949 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
950 * </ul> | |
951 * | |
952 * @deprecated This image is not used | |
953 */ | |
954 public void setDisabledImage (Image image) { | |
955 checkWidget(); | |
956 if (image !is null && image.isDisposed ()) { | |
957 SWT.error(SWT.ERROR_INVALID_ARGUMENT); | |
958 } | |
959 this.disabledImage = image; | |
960 } | |
961 /** | |
962 * Sets the font that the receiver will use to paint textual information | |
963 * for this item to the font specified by the argument, or to the default font | |
964 * for that kind of control if the argument is null. | |
965 * | |
966 * @param font the new font (or null) | |
967 * | |
968 * @exception IllegalArgumentException <ul> | |
969 * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> | |
970 * </ul> | |
971 * @exception SWTException <ul> | |
972 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
973 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
974 * </ul> | |
975 * | |
976 * @since 3.0 | |
977 */ | |
978 public void setFont (Font font){ | |
979 checkWidget(); | |
980 if (font !is null && font.isDisposed ()) { | |
981 SWT.error(SWT.ERROR_INVALID_ARGUMENT); | |
982 } | |
983 if (font is null && this.font is null) return; | |
984 if (font !is null && font==this.font) return; | |
985 this.font = font; | |
986 if (!parent.updateTabHeight(false)) { | |
987 parent.updateItems(); | |
988 parent.redrawTabs(); | |
989 } | |
990 } | |
991 public override void setImage (Image image) { | |
992 checkWidget(); | |
993 if (image !is null && image.isDisposed ()) { | |
994 SWT.error(SWT.ERROR_INVALID_ARGUMENT); | |
995 } | |
996 Image oldImage = getImage(); | |
997 if (image is null && oldImage is null) return; | |
998 if (image !is null && image==oldImage) return; | |
999 super.setImage(image); | |
1000 if (!parent.updateTabHeight(false)) { | |
1001 // If image is the same size as before, | |
1002 // redraw only the image | |
1003 if (oldImage !is null && image !is null) { | |
1004 Rectangle oldBounds = oldImage.getBounds(); | |
1005 Rectangle bounds = image.getBounds(); | |
1006 if (bounds.width is oldBounds.width && bounds.height is oldBounds.height) { | |
1007 if (showing) { | |
1008 bool selected = parent.indexOf(this) is parent.selectedIndex; | |
1009 if (selected || parent.showUnselectedImage) { | |
1010 int imageX = x + LEFT_MARGIN, maxImageWidth; | |
1011 if (selected) { | |
1012 if (parent.single && (parent.showClose || showClose)) imageX += CTabFolder.BUTTON_SIZE; | |
1013 int rightEdge = Math.min (x + width, parent.getRightItemEdge()); | |
1014 maxImageWidth = rightEdge - imageX - RIGHT_MARGIN; | |
1015 if (!parent.single && closeRect.width > 0) maxImageWidth -= closeRect.width + INTERNAL_SPACING; | |
1016 } else { | |
1017 maxImageWidth = x + width - imageX - RIGHT_MARGIN; | |
1018 if (parent.showUnselectedClose && (parent.showClose || showClose)) { | |
1019 maxImageWidth -= closeRect.width + INTERNAL_SPACING; | |
1020 } | |
1021 } | |
1022 if (bounds.width < maxImageWidth) { | |
1023 int imageY = y + (height - bounds.height) / 2 + (parent.onBottom ? -1 : 1); | |
1024 parent.redraw(imageX, imageY, bounds.width, bounds.height, false); | |
1025 } | |
1026 } | |
1027 } | |
1028 return; | |
1029 } | |
1030 } | |
1031 parent.updateItems(); | |
1032 parent.redrawTabs(); | |
1033 } | |
1034 } | |
1035 /** | |
1036 * Sets to <code>true</code> to indicate that the receiver's close button should be shown. | |
1037 * If the parent (CTabFolder) was created with SWT.CLOSE style, changing this value has | |
1038 * no effect. | |
1039 * | |
1040 * @param close the new state of the close button | |
1041 * | |
1042 * @exception SWTException <ul> | |
1043 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1044 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1045 * </ul> | |
1046 * | |
1047 * @since 3.4 | |
1048 */ | |
1049 public void setShowClose(bool close) { | |
1050 checkWidget(); | |
1051 if (showClose is close) return; | |
1052 showClose = close; | |
1053 parent.updateItems(); | |
1054 parent.redrawTabs(); | |
1055 } | |
1056 public override void setText (String string) { | |
1057 checkWidget(); | |
1058 // SWT extension: allow null for zero length string | |
1059 //if (string is null) SWT.error (SWT.ERROR_NULL_ARGUMENT); | |
1060 if (string.equals (getText())) return; | |
1061 super.setText(string); | |
1062 shortenedText = null; | |
1063 shortenedTextWidth = 0; | |
1064 if (!parent.updateTabHeight(false)) { | |
1065 parent.updateItems(); | |
1066 parent.redrawTabs(); | |
1067 } | |
1068 } | |
1069 /** | |
1070 * Sets the receiver's tool tip text to the argument, which | |
1071 * may be null indicating that no tool tip text should be shown. | |
1072 * | |
1073 * @param string the new tool tip text (or null) | |
1074 * | |
1075 * @exception SWTException <ul> | |
1076 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
1077 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1078 * </ul> | |
1079 */ | |
1080 public void setToolTipText (String string) { | |
1081 checkWidget(); | |
1082 toolTipText = string; | |
1083 } | |
1084 | |
1085 } |