Mercurial > projects > dwt-mac
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 } |