comparison org.eclipse.swt.win32.win32.x86/src/org/eclipse/swt/custom/CBanner.d @ 0:6dd524f61e62

add dwt win and basic java stuff
author Frank Benoit <benoit@tionex.de>
date Mon, 02 Mar 2009 14:44:16 +0100
parents
children 6bf2837c50fe
comparison
equal deleted inserted replaced
-1:000000000000 0:6dd524f61e62
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.CBanner;
14
15
16
17 import org.eclipse.swt.SWT;
18 import org.eclipse.swt.SWTException;
19 import org.eclipse.swt.graphics.Color;
20 import org.eclipse.swt.graphics.Cursor;
21 import org.eclipse.swt.graphics.GC;
22 import org.eclipse.swt.graphics.Point;
23 import org.eclipse.swt.graphics.RGB;
24 import org.eclipse.swt.graphics.Rectangle;
25 import org.eclipse.swt.widgets.Composite;
26 import org.eclipse.swt.widgets.Control;
27 import org.eclipse.swt.widgets.Event;
28 import org.eclipse.swt.widgets.Layout;
29 import org.eclipse.swt.widgets.Listener;
30 import org.eclipse.swt.custom.CBannerLayout;
31
32 import Math = tango.math.Math;
33
34
35 /**
36 * Instances of this class implement a Composite that lays out its
37 * children and allows programmatic control of the layout. It draws
38 * a separator between the left and right children which can be dragged
39 * to resize the right control.
40 * CBanner is used in the workbench to layout the toolbar area and
41 * perspective switching toolbar.
42 * <p>
43 * Note that although this class is a subclass of <code>Composite</code>,
44 * it does not make sense to set a layout on it.
45 * </p><p>
46 * <dl>
47 * <dt><b>Styles:</b></dt>
48 * <dd>NONE</dd>
49 * <dt><b>Events:</b></dt>
50 * <dd>(None)</dd>
51 * </dl>
52 * <p>
53 * IMPORTANT: This class is <em>not</em> intended to be subclassed.
54 * </p>
55 *
56 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
57 *
58 * @since 3.0
59 */
60
61 public class CBanner : Composite {
62
63 Control left;
64 Control right;
65 Control bottom;
66
67 bool simple = true;
68
69 int[] curve;
70 int curveStart = 0;
71 Rectangle curveRect;
72 int curve_width = 5;
73 int curve_indent = -2;
74
75 int rightWidth = SWT.DEFAULT;
76 int rightMinWidth = 0;
77 int rightMinHeight = 0;
78 Cursor resizeCursor;
79 bool dragging = false;
80 int rightDragDisplacement = 0;
81
82 static const int OFFSCREEN = -200;
83 static const int BORDER_BOTTOM = 2;
84 static const int BORDER_TOP = 3;
85 static const int BORDER_STRIPE = 1;
86 static const int CURVE_TAIL = 200;
87 static const int BEZIER_RIGHT = 30;
88 static const int BEZIER_LEFT = 30;
89 static const int MIN_LEFT = 10;
90 static int BORDER1 = SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW;
91
92
93 /**
94 * Constructs a new instance of this class given its parent
95 * and a style value describing its behavior and appearance.
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 widget which will be the parent of the new instance (cannot be null)
107 * @param style the style of widget 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 */
117 public this(Composite parent, int style) {
118 curveRect = new Rectangle(0, 0, 0, 0);
119 super(parent, checkStyle(style));
120 super.setLayout(new CBannerLayout());
121 resizeCursor = new Cursor(getDisplay(), SWT.CURSOR_SIZEWE);
122
123 Listener listener = new class() Listener {
124 public void handleEvent(Event e) {
125 switch (e.type) {
126 case SWT.Dispose:
127 onDispose(); break;
128 case SWT.MouseDown:
129 onMouseDown (e.x, e.y); break;
130 case SWT.MouseExit:
131 onMouseExit(); break;
132 case SWT.MouseMove:
133 onMouseMove(e.x, e.y); break;
134 case SWT.MouseUp:
135 onMouseUp(); break;
136 case SWT.Paint:
137 onPaint(e.gc); break;
138 case SWT.Resize:
139 onResize(); break;
140 default:
141 }
142 }
143 };
144 int[] events = [SWT.Dispose, SWT.MouseDown, SWT.MouseExit, SWT.MouseMove, SWT.MouseUp, SWT.Paint, SWT.Resize];
145 for (int i = 0; i < events.length; i++) {
146 addListener(events[i], listener);
147 }
148 }
149 static int[] bezier(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3, int count) {
150 // The parametric equations for a Bezier curve for x[t] and y[t] where 0 <= t <=1 are:
151 // x[t] = x0+3(x1-x0)t+3(x0+x2-2x1)t^2+(x3-x0+3x1-3x2)t^3
152 // y[t] = y0+3(y1-y0)t+3(y0+y2-2y1)t^2+(y3-y0+3y1-3y2)t^3
153 double a0 = x0;
154 double a1 = 3*(x1 - x0);
155 double a2 = 3*(x0 + x2 - 2*x1);
156 double a3 = x3 - x0 + 3*x1 - 3*x2;
157 double b0 = y0;
158 double b1 = 3*(y1 - y0);
159 double b2 = 3*(y0 + y2 - 2*y1);
160 double b3 = y3 - y0 + 3*y1 - 3*y2;
161
162 int[] polygon = new int[2*count + 2];
163 for (int i = 0; i <= count; i++) {
164 double t = cast(double)i / cast(double)count;
165 polygon[2*i] = cast(int)(a0 + a1*t + a2*t*t + a3*t*t*t);
166 polygon[2*i + 1] = cast(int)(b0 + b1*t + b2*t*t + b3*t*t*t);
167 }
168 return polygon;
169 }
170 static int checkStyle (int style) {
171 return SWT.NONE;
172 }
173 /**
174 * Returns the Control that appears on the bottom side of the banner.
175 *
176 * @return the control that appears on the bottom side of the banner or null
177 *
178 * @exception SWTException <ul>
179 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
180 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
181 * </ul>
182 *
183 * @since 3.0
184 */
185 public Control getBottom() {
186 checkWidget();
187 return bottom;
188 }
189 public override Rectangle getClientArea() {
190 return new Rectangle(0, 0, 0, 0);
191 }
192
193 /**
194 * Returns the Control that appears on the left side of the banner.
195 *
196 * @return the control that appears on the left side of the banner or null
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 * @since 3.0
204 */
205 public Control getLeft() {
206 checkWidget();
207 return left;
208 }
209
210 /**
211 * Returns the Control that appears on the right side of the banner.
212 *
213 * @return the control that appears on the right side of the banner or null
214 *
215 * @exception SWTException <ul>
216 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
217 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
218 * </ul>
219 *
220 * @since 3.0
221 */
222 public Control getRight() {
223 checkWidget();
224 return right;
225 }
226 /**
227 * Returns the minimum size of the control that appears on the right of the banner.
228 *
229 * @return the minimum size of the control that appears on the right of the banner
230 *
231 * @since 3.1
232 */
233 public Point getRightMinimumSize() {
234 checkWidget();
235 return new Point(rightMinWidth, rightMinHeight);
236 }
237 /**
238 * Returns the width of the control that appears on the right of the banner.
239 *
240 * @return the width of the control that appears on the right of the banner
241 *
242 * @since 3.0
243 */
244 public int getRightWidth() {
245 checkWidget();
246 if (right is null) return 0;
247 if (rightWidth is SWT.DEFAULT) {
248 Point size = right.computeSize(SWT.DEFAULT, SWT.DEFAULT, false);
249 return size.x;
250 }
251 return rightWidth;
252 }
253 /**
254 * Returns <code>true</code> if the CBanner is rendered
255 * with a simple, traditional shape.
256 *
257 * @return <code>true</code> if the CBanner is rendered with a simple shape
258 *
259 * @since 3.0
260 */
261 public bool getSimple() {
262 checkWidget();
263 return simple;
264 }
265 void onDispose() {
266 if (resizeCursor !is null) resizeCursor.dispose();
267 resizeCursor = null;
268 left = null;
269 right = null;
270 bottom = null;
271 }
272 void onMouseDown (int x, int y) {
273 if (curveRect.contains(x, y)) {
274 dragging = true;
275 rightDragDisplacement = curveStart - x + curve_width - curve_indent;
276 }
277 }
278 void onMouseExit() {
279 if (!dragging) setCursor(null);
280 }
281 void onMouseMove(int x, int y) {
282 if (dragging) {
283 Point size = getSize();
284 if (!(0 < x && x < size.x)) return;
285 rightWidth = Math.max(0, size.x - x - rightDragDisplacement);
286 if (rightMinWidth is SWT.DEFAULT) {
287 Point minSize = right.computeSize(rightMinWidth, rightMinHeight);
288 rightWidth = Math.max(minSize.x, rightWidth);
289 } else {
290 rightWidth = Math.max(rightMinWidth, rightWidth);
291 }
292 layout(false);
293 return;
294 }
295 if (curveRect.contains(x, y)) {
296 setCursor(resizeCursor);
297 } else {
298 setCursor(null);
299 }
300 }
301 void onMouseUp () {
302 dragging = false;
303 }
304 void onPaint(GC gc) {
305 // Useful for debugging paint problems
306 // {
307 // Point size = getSize();
308 // gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_GREEN));
309 // gc.fillRectangle(-10, -10, size.x+20, size.y+20);
310 // }
311 if (left is null && right is null) return;
312 Point size = getSize();
313 Color border1 = getDisplay().getSystemColor(BORDER1);
314 if (bottom !is null) {
315 int y = bottom.getBounds().y - BORDER_STRIPE - 1;
316 gc.setForeground(border1);
317 gc.drawLine(0, y, size.x, y);
318 }
319 if (left is null || right is null) return;
320 int[] line1 = new int[curve.length+6];
321 int index = 0;
322 int x = curveStart;
323 line1[index++] = x + 1;
324 line1[index++] = size.y - BORDER_STRIPE;
325 for (int i = 0; i < curve.length/2; i++) {
326 line1[index++]=x+curve[2*i];
327 line1[index++]=curve[2*i+1];
328 }
329 line1[index++] = x + curve_width;
330 line1[index++] = 0;
331 line1[index++] = size.x;
332 line1[index++] = 0;
333
334 Color background = getBackground();
335
336 if (getDisplay().getDepth() >= 15) {
337 // Anti- aliasing
338 int[] line2 = new int[line1.length];
339 index = 0;
340 for (int i = 0; i < line1.length/2; i++) {
341 line2[index] = line1[index++] - 1;
342 line2[index] = line1[index++];
343 }
344 int[] line3 = new int[line1.length];
345 index = 0;
346 for (int i = 0; i < line1.length/2; i++) {
347 line3[index] = line1[index++] + 1;
348 line3[index] = line1[index++];
349 }
350 RGB from = border1.getRGB();
351 RGB to = background.getRGB();
352 int red = from.red + 3*(to.red - from.red)/4;
353 int green = from.green + 3*(to.green - from.green)/4;
354 int blue = from.blue + 3*(to.blue - from.blue)/4;
355 Color color = new Color(getDisplay(), red, green, blue);
356 gc.setForeground(color);
357 gc.drawPolyline(line2);
358 gc.drawPolyline(line3);
359 color.dispose();
360
361 // draw tail fading to background
362 int x1 = Math.max(0, curveStart - CURVE_TAIL);
363 gc.setForeground(background);
364 gc.setBackground(border1);
365 gc.fillGradientRectangle(x1, size.y - BORDER_STRIPE, curveStart-x1+1, 1, false);
366 } else {
367 // draw solid tail
368 int x1 = Math.max(0, curveStart - CURVE_TAIL);
369 gc.setForeground(border1);
370 gc.drawLine(x1, size.y - BORDER_STRIPE, curveStart+1, size.y - BORDER_STRIPE);
371 }
372
373 // draw border
374 gc.setForeground(border1);
375 gc.drawPolyline(line1);
376 }
377
378 void onResize() {
379 updateCurve(getSize().y);
380 }
381 /**
382 * Set the control that appears on the bottom side of the banner.
383 * The bottom control is optional. Setting the bottom control to null will remove it from
384 * the banner - however, the creator of the control must dispose of the control.
385 *
386 * @param control the control to be displayed on the bottom or null
387 *
388 * @exception SWTException <ul>
389 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
390 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
391 * <li>ERROR_INVALID_ARGUMENT - if the bottom control was not created as a child of the receiver</li>
392 * </ul>
393 *
394 * @since 3.0
395 */
396 public void setBottom(Control control) {
397 checkWidget();
398 if (control !is null && control.getParent() !is this) {
399 SWT.error(SWT.ERROR_INVALID_ARGUMENT);
400 }
401 if (bottom !is null && !bottom.isDisposed()) {
402 Point size = bottom.getSize();
403 bottom.setLocation(OFFSCREEN - size.x, OFFSCREEN - size.y);
404 }
405 bottom = control;
406 layout(false);
407 }
408 /**
409 * Sets the layout which is associated with the receiver to be
410 * the argument which may be null.
411 * <p>
412 * Note: No Layout can be set on this Control because it already
413 * manages the size and position of its children.
414 * </p>
415 *
416 * @param layout the receiver's new layout or null
417 *
418 * @exception SWTException <ul>
419 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
420 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
421 * </ul>
422 */
423 public override void setLayout (Layout layout) {
424 checkWidget();
425 return;
426 }
427
428 /**
429 * Set the control that appears on the left side of the banner.
430 * The left control is optional. Setting the left control to null will remove it from
431 * the banner - however, the creator of the control must dispose of the control.
432 *
433 * @param control the control to be displayed on the left or null
434 *
435 * @exception SWTException <ul>
436 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
437 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
438 * <li>ERROR_INVALID_ARGUMENT - if the left control was not created as a child of the receiver</li>
439 * </ul>
440 *
441 * @since 3.0
442 */
443 public void setLeft(Control control) {
444 checkWidget();
445 if (control !is null && control.getParent() !is this) {
446 SWT.error(SWT.ERROR_INVALID_ARGUMENT);
447 }
448 if (left !is null && !left.isDisposed()) {
449 Point size = left.getSize();
450 left.setLocation(OFFSCREEN - size.x, OFFSCREEN - size.y);
451 }
452 left = control;
453 layout(false);
454 }
455 /**
456 * Set the control that appears on the right side of the banner.
457 * The right control is optional. Setting the right control to null will remove it from
458 * the banner - however, the creator of the control must dispose of the control.
459 *
460 * @param control the control to be displayed on the right or null
461 *
462 * @exception SWTException <ul>
463 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
464 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
465 * <li>ERROR_INVALID_ARGUMENT - if the right control was not created as a child of the receiver</li>
466 * </ul>
467 *
468 * @since 3.0
469 */
470 public void setRight(Control control) {
471 checkWidget();
472 if (control !is null && control.getParent() !is this) {
473 SWT.error(SWT.ERROR_INVALID_ARGUMENT);
474 }
475 if (right !is null && !right.isDisposed()) {
476 Point size = right.getSize();
477 right.setLocation(OFFSCREEN - size.x, OFFSCREEN - size.y);
478 }
479 right = control;
480 layout(false);
481 }
482 /**
483 * Set the minimum height of the control that appears on the right side of the banner.
484 *
485 * @param size the minimum size of the control on the right
486 *
487 * @exception SWTException <ul>
488 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
489 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
490 * <li>ERROR_INVALID_ARGUMENT - if the size is null or the values of size are less than SWT.DEFAULT</li>
491 * </ul>
492 *
493 * @since 3.1
494 */
495 public void setRightMinimumSize(Point size) {
496 checkWidget();
497 if (size is null || size.x < SWT.DEFAULT || size.y < SWT.DEFAULT) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
498 rightMinWidth = size.x;
499 rightMinHeight = size.y;
500 layout(false);
501 }
502 /**
503 * Set the width of the control that appears on the right side of the banner.
504 *
505 * @param width the width of the control on the right
506 *
507 * @exception SWTException <ul>
508 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
509 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
510 * <li>ERROR_INVALID_ARGUMENT - if width is less than SWT.DEFAULT</li>
511 * </ul>
512 *
513 * @since 3.0
514 */
515 public void setRightWidth(int width) {
516 checkWidget();
517 if (width < SWT.DEFAULT) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
518 rightWidth = width;
519 layout(false);
520 }
521 /**
522 * Sets the shape that the CBanner will use to render itself.
523 *
524 * @param simple <code>true</code> if the CBanner should render itself in a simple, traditional style
525 *
526 * @exception SWTException <ul>
527 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
528 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
529 * </ul>
530 *
531 * @since 3.0
532 */
533 public void setSimple(bool simple) {
534 checkWidget();
535 if (this.simple !is simple) {
536 this.simple = simple;
537 if (simple) {
538 curve_width = 5;
539 curve_indent = -2;
540 } else {
541 curve_width = 50;
542 curve_indent = 5;
543 }
544 updateCurve(getSize().y);
545 layout(false);
546 redraw();
547 }
548 }
549 void updateCurve(int height) {
550 int h = height - BORDER_STRIPE;
551 if (simple) {
552 curve = [0,h, 1,h, 2,h-1, 3,h-2,
553 3,2, 4,1, 5,0];
554 } else {
555 curve = bezier(0, h+1, BEZIER_LEFT, h+1,
556 curve_width-BEZIER_RIGHT, 0, curve_width, 0,
557 curve_width);
558 }
559 }
560 }