comparison dwt/custom/CBanner.d @ 41:6337764516f1

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