KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > swt > custom > CBanner


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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.swt.custom;
12
13
14 import org.eclipse.swt.graphics.*;
15 import org.eclipse.swt.widgets.*;
16 import org.eclipse.swt.*;
17
18 /**
19  * Instances of this class implement a Composite that lays out its
20  * children and allows programmatic control of the layout. It draws
21  * a separator between the left and right children which can be dragged
22  * to resize the right control.
23  * CBanner is used in the workbench to layout the toolbar area and
24  * perspective switching toolbar.
25  * <p>
26  * Note that although this class is a subclass of <code>Composite</code>,
27  * it does not make sense to set a layout on it.
28  * </p><p>
29  * <dl>
30  * <dt><b>Styles:</b></dt>
31  * <dd>NONE</dd>
32  * <dt><b>Events:</b></dt>
33  * <dd>(None)</dd>
34  * </dl>
35  * <p>
36  * IMPORTANT: This class is <em>not</em> intended to be subclassed.
37  * </p>
38  *
39  * @since 3.0
40  */

41
42 public class CBanner extends Composite {
43
44     Control left;
45     Control right;
46     Control bottom;
47     
48     boolean simple = true;
49     
50     int[] curve = new int[0];
51     int curveStart = 0;
52     Rectangle curveRect = new Rectangle(0, 0, 0, 0);
53     int curve_width = 5;
54     int curve_indent = -2;
55     
56     int rightWidth = SWT.DEFAULT;
57     int rightMinWidth = 0;
58     int rightMinHeight = 0;
59     Cursor resizeCursor;
60     boolean dragging = false;
61     int rightDragDisplacement = 0;
62     
63     static final int OFFSCREEN = -200;
64     static final int BORDER_BOTTOM = 2;
65     static final int BORDER_TOP = 3;
66     static final int BORDER_STRIPE = 1;
67     static final int CURVE_TAIL = 200;
68     static final int BEZIER_RIGHT = 30;
69     static final int BEZIER_LEFT = 30;
70     static final int MIN_LEFT = 10;
71     static int BORDER1 = SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW;
72     
73         
74 /**
75  * Constructs a new instance of this class given its parent
76  * and a style value describing its behavior and appearance.
77  * <p>
78  * The style value is either one of the style constants defined in
79  * class <code>SWT</code> which is applicable to instances of this
80  * class, or must be built by <em>bitwise OR</em>'ing together
81  * (that is, using the <code>int</code> "|" operator) two or more
82  * of those <code>SWT</code> style constants. The class description
83  * lists the style constants that are applicable to the class.
84  * Style bits are also inherited from superclasses.
85  * </p>
86  *
87  * @param parent a widget which will be the parent of the new instance (cannot be null)
88  * @param style the style of widget to construct
89  *
90  * @exception IllegalArgumentException <ul>
91  * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
92  * </ul>
93  * @exception SWTException <ul>
94  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
95  * </ul>
96  *
97  */

98 public CBanner(Composite parent, int style) {
99     super(parent, checkStyle(style));
100     super.setLayout(new CBannerLayout());
101     resizeCursor = new Cursor(getDisplay(), SWT.CURSOR_SIZEWE);
102     
103     Listener listener = new Listener() {
104         public void handleEvent(Event e) {
105             switch (e.type) {
106                 case SWT.Dispose:
107                     onDispose(); break;
108                 case SWT.MouseDown:
109                     onMouseDown (e.x, e.y); break;
110                 case SWT.MouseExit:
111                     onMouseExit(); break;
112                 case SWT.MouseMove:
113                     onMouseMove(e.x, e.y); break;
114                 case SWT.MouseUp:
115                     onMouseUp(); break;
116                 case SWT.Paint:
117                     onPaint(e.gc); break;
118                 case SWT.Resize:
119                     onResize(); break;
120             }
121         }
122     };
123     int[] events = new int[] {SWT.Dispose, SWT.MouseDown, SWT.MouseExit, SWT.MouseMove, SWT.MouseUp, SWT.Paint, SWT.Resize};
124     for (int i = 0; i < events.length; i++) {
125         addListener(events[i], listener);
126     }
127 }
128 static int[] bezier(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3, int count) {
129     // The parametric equations for a Bezier curve for x[t] and y[t] where 0 <= t <=1 are:
130
// x[t] = x0+3(x1-x0)t+3(x0+x2-2x1)t^2+(x3-x0+3x1-3x2)t^3
131
// y[t] = y0+3(y1-y0)t+3(y0+y2-2y1)t^2+(y3-y0+3y1-3y2)t^3
132
double a0 = x0;
133     double a1 = 3*(x1 - x0);
134     double a2 = 3*(x0 + x2 - 2*x1);
135     double a3 = x3 - x0 + 3*x1 - 3*x2;
136     double b0 = y0;
137     double b1 = 3*(y1 - y0);
138     double b2 = 3*(y0 + y2 - 2*y1);
139     double b3 = y3 - y0 + 3*y1 - 3*y2;
140
141     int[] polygon = new int[2*count + 2];
142     for (int i = 0; i <= count; i++) {
143         double t = (double)i / (double)count;
144         polygon[2*i] = (int)(a0 + a1*t + a2*t*t + a3*t*t*t);
145         polygon[2*i + 1] = (int)(b0 + b1*t + b2*t*t + b3*t*t*t);
146     }
147     return polygon;
148 }
149 static int checkStyle (int style) {
150     return SWT.NONE;
151 }
152 /**
153 * Returns the Control that appears on the bottom side of the banner.
154 *
155 * @return the control that appears on the bottom side of the banner or null
156 *
157 * @exception SWTException <ul>
158 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
159 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
160 * </ul>
161 *
162 * @since 3.0
163 */

164 public Control getBottom() {
165     checkWidget();
166     return bottom;
167 }
168 public Rectangle getClientArea() {
169     return new Rectangle(0, 0, 0, 0);
170 }
171
172 /**
173 * Returns the Control that appears on the left side of the banner.
174 *
175 * @return the control that appears on the left side of the banner or null
176 *
177 * @exception SWTException <ul>
178 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
179 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
180 * </ul>
181 *
182 * @since 3.0
183 */

184 public Control getLeft() {
185     checkWidget();
186     return left;
187 }
188
189 /**
190 * Returns the Control that appears on the right side of the banner.
191 *
192 * @return the control that appears on the right side of the banner or null
193 *
194 * @exception SWTException <ul>
195 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
196 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
197 * </ul>
198 *
199 * @since 3.0
200 */

201 public Control getRight() {
202     checkWidget();
203     return right;
204 }
205 /**
206  * Returns the minimum size of the control that appears on the right of the banner.
207  *
208  * @return the minimum size of the control that appears on the right of the banner
209  *
210  * @since 3.1
211  */

212 public Point getRightMinimumSize() {
213     checkWidget();
214     return new Point(rightMinWidth, rightMinHeight);
215 }
216 /**
217  * Returns the width of the control that appears on the right of the banner.
218  *
219  * @return the width of the control that appears on the right of the banner
220  *
221  * @since 3.0
222  */

223 public int getRightWidth() {
224     checkWidget();
225     if (right == null) return 0;
226     if (rightWidth == SWT.DEFAULT) {
227         Point size = right.computeSize(SWT.DEFAULT, SWT.DEFAULT, false);
228         return size.x;
229     }
230     return rightWidth;
231 }
232 /**
233  * Returns <code>true</code> if the CBanner is rendered
234  * with a simple, traditional shape.
235  *
236  * @return <code>true</code> if the CBanner is rendered with a simple shape
237  *
238  * @since 3.0
239  */

240 public boolean getSimple() {
241     checkWidget();
242     return simple;
243 }
244 void onDispose() {
245     if (resizeCursor != null) resizeCursor.dispose();
246     resizeCursor = null;
247     left = null;
248     right = null;
249     bottom = null;
250 }
251 void onMouseDown (int x, int y) {
252     if (curveRect.contains(x, y)) {
253         dragging = true;
254         rightDragDisplacement = curveStart - x + curve_width - curve_indent;
255     }
256 }
257 void onMouseExit() {
258     if (!dragging) setCursor(null);
259 }
260 void onMouseMove(int x, int y) {
261     if (dragging) {
262         Point size = getSize();
263         if (!(0 < x && x < size.x)) return;
264         rightWidth = Math.max(0, size.x - x - rightDragDisplacement);
265         if (rightMinWidth == SWT.DEFAULT) {
266             Point minSize = right.computeSize(rightMinWidth, rightMinHeight);
267             rightWidth = Math.max(minSize.x, rightWidth);
268         } else {
269             rightWidth = Math.max(rightMinWidth, rightWidth);
270         }
271         layout(false);
272         return;
273     }
274     if (curveRect.contains(x, y)) {
275         setCursor(resizeCursor);
276     } else {
277         setCursor(null);
278     }
279 }
280 void onMouseUp () {
281     dragging = false;
282 }
283 void onPaint(GC gc) {
284 // Useful for debugging paint problems
285
// {
286
// Point size = getSize();
287
// gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_GREEN));
288
// gc.fillRectangle(-10, -10, size.x+20, size.y+20);
289
// }
290
if (left == null && right == null) return;
291     Point size = getSize();
292     Color border1 = getDisplay().getSystemColor(BORDER1);
293     if (bottom != null) {
294         int y = bottom.getBounds().y - BORDER_STRIPE - 1;
295         gc.setForeground(border1);
296         gc.drawLine(0, y, size.x, y);
297     }
298     if (left == null || right == null) return;
299     int[] line1 = new int[curve.length+6];
300     int index = 0;
301     int x = curveStart;
302     line1[index++] = x + 1;
303     line1[index++] = size.y - BORDER_STRIPE;
304     for (int i = 0; i < curve.length/2; i++) {
305         line1[index++]=x+curve[2*i];
306         line1[index++]=curve[2*i+1];
307     }
308     line1[index++] = x + curve_width;
309     line1[index++] = 0;
310     line1[index++] = size.x;
311     line1[index++] = 0;
312     
313     Color background = getBackground();
314         
315     if (getDisplay().getDepth() >= 15) {
316         // Anti- aliasing
317
int[] line2 = new int[line1.length];
318         index = 0;
319         for (int i = 0; i < line1.length/2; i++) {
320             line2[index] = line1[index++] - 1;
321             line2[index] = line1[index++];
322         }
323         int[] line3 = new int[line1.length];
324         index = 0;
325         for (int i = 0; i < line1.length/2; i++) {
326             line3[index] = line1[index++] + 1;
327             line3[index] = line1[index++];
328         }
329         RGB from = border1.getRGB();
330         RGB to = background.getRGB();
331         int red = from.red + 3*(to.red - from.red)/4;
332         int green = from.green + 3*(to.green - from.green)/4;
333         int blue = from.blue + 3*(to.blue - from.blue)/4;
334         Color color = new Color(getDisplay(), red, green, blue);
335         gc.setForeground(color);
336         gc.drawPolyline(line2);
337         gc.drawPolyline(line3);
338         color.dispose();
339         
340         // draw tail fading to background
341
int x1 = Math.max(0, curveStart - CURVE_TAIL);
342         gc.setForeground(background);
343         gc.setBackground(border1);
344         gc.fillGradientRectangle(x1, size.y - BORDER_STRIPE, curveStart-x1+1, 1, false);
345     } else {
346         // draw solid tail
347
int x1 = Math.max(0, curveStart - CURVE_TAIL);
348         gc.setForeground(border1);
349         gc.drawLine(x1, size.y - BORDER_STRIPE, curveStart+1, size.y - BORDER_STRIPE);
350     }
351     
352     // draw border
353
gc.setForeground(border1);
354     gc.drawPolyline(line1);
355 }
356
357 void onResize() {
358     updateCurve(getSize().y);
359 }
360 /**
361 * Set the control that appears on the bottom side of the banner.
362 * The bottom control is optional. Setting the bottom control to null will remove it from
363 * the banner - however, the creator of the control must dispose of the control.
364 *
365 * @param control the control to be displayed on the bottom or null
366 *
367 * @exception SWTException <ul>
368 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
369 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
370 * <li>ERROR_INVALID_ARGUMENT - if the bottom control was not created as a child of the receiver</li>
371 * </ul>
372 *
373 * @since 3.0
374 */

375 public void setBottom(Control control) {
376     checkWidget();
377     if (control != null && control.getParent() != this) {
378         SWT.error(SWT.ERROR_INVALID_ARGUMENT);
379     }
380     if (bottom != null && !bottom.isDisposed()) {
381         Point size = bottom.getSize();
382         bottom.setLocation(OFFSCREEN - size.x, OFFSCREEN - size.y);
383     }
384     bottom = control;
385     layout(false);
386 }
387 /**
388  * Sets the layout which is associated with the receiver to be
389  * the argument which may be null.
390  * <p>
391  * Note: No Layout can be set on this Control because it already
392  * manages the size and position of its children.
393  * </p>
394  *
395  * @param layout the receiver's new layout or null
396  *
397  * @exception SWTException <ul>
398  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
399  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
400  * </ul>
401  */

402 public void setLayout (Layout layout) {
403     checkWidget();
404     return;
405 }
406
407 /**
408 * Set the control that appears on the left side of the banner.
409 * The left control is optional. Setting the left control to null will remove it from
410 * the banner - however, the creator of the control must dispose of the control.
411 *
412 * @param control the control to be displayed on the left or null
413 *
414 * @exception SWTException <ul>
415 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
416 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
417 * <li>ERROR_INVALID_ARGUMENT - if the left control was not created as a child of the receiver</li>
418 * </ul>
419 *
420 * @since 3.0
421 */

422 public void setLeft(Control control) {
423     checkWidget();
424     if (control != null && control.getParent() != this) {
425         SWT.error(SWT.ERROR_INVALID_ARGUMENT);
426     }
427     if (left != null && !left.isDisposed()) {
428         Point size = left.getSize();
429         left.setLocation(OFFSCREEN - size.x, OFFSCREEN - size.y);
430     }
431     left = control;
432     layout(false);
433 }
434 /**
435 * Set the control that appears on the right side of the banner.
436 * The right control is optional. Setting the right control to null will remove it from
437 * the banner - however, the creator of the control must dispose of the control.
438 *
439 * @param control the control to be displayed on the right or null
440 *
441 * @exception SWTException <ul>
442 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
443 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
444 * <li>ERROR_INVALID_ARGUMENT - if the right control was not created as a child of the receiver</li>
445 * </ul>
446 *
447 * @since 3.0
448 */

449 public void setRight(Control control) {
450     checkWidget();
451     if (control != null && control.getParent() != this) {
452         SWT.error(SWT.ERROR_INVALID_ARGUMENT);
453     }
454     if (right != null && !right.isDisposed()) {
455         Point size = right.getSize();
456         right.setLocation(OFFSCREEN - size.x, OFFSCREEN - size.y);
457     }
458     right = control;
459     layout(false);
460 }
461 /**
462  * Set the minimum height of the control that appears on the right side of the banner.
463  *
464  * @param size the minimum size of the control on the right
465  *
466  * @exception SWTException <ul>
467  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
468  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
469  * <li>ERROR_INVALID_ARGUMENT - if the size is null or the values of size are less than SWT.DEFAULT</li>
470  * </ul>
471  *
472  * @since 3.1
473  */

474 public void setRightMinimumSize(Point size) {
475     checkWidget();
476     if (size == null || size.x < SWT.DEFAULT || size.y < SWT.DEFAULT) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
477     rightMinWidth = size.x;
478     rightMinHeight = size.y;
479     layout(false);
480 }
481 /**
482  * Set the width of the control that appears on the right side of the banner.
483  *
484  * @param width the width of the control on the right
485  *
486  * @exception SWTException <ul>
487  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
488  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
489  * <li>ERROR_INVALID_ARGUMENT - if width is less than SWT.DEFAULT</li>
490  * </ul>
491  *
492  * @since 3.0
493  */

494 public void setRightWidth(int width) {
495     checkWidget();
496     if (width < SWT.DEFAULT) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
497     rightWidth = width;
498     layout(false);
499 }
500 /**
501  * Sets the shape that the CBanner will use to render itself.
502  *
503  * @param simple <code>true</code> if the CBanner should render itself in a simple, traditional style
504  *
505  * @exception SWTException <ul>
506  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
507  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
508  * </ul>
509  *
510  * @since 3.0
511  */

512 public void setSimple(boolean simple) {
513     checkWidget();
514     if (this.simple != simple) {
515         this.simple = simple;
516         if (simple) {
517             curve_width = 5;
518             curve_indent = -2;
519         } else {
520             curve_width = 50;
521             curve_indent = 5;
522         }
523         updateCurve(getSize().y);
524         layout(false);
525         redraw();
526     }
527 }
528 void updateCurve(int height) {
529     int h = height - BORDER_STRIPE;
530     if (simple) {
531         curve = new int[] {0,h, 1,h, 2,h-1, 3,h-2,
532                                    3,2, 4,1, 5,0,};
533     } else {
534         curve = bezier(0, h+1, BEZIER_LEFT, h+1,
535                              curve_width-BEZIER_RIGHT, 0, curve_width, 0,
536                              curve_width);
537     }
538 }
539 }
540
Popular Tags