comparison dwt/widgets/Canvas.d @ 0:380af2bdd8e5

Upload of whole dwt tree
author Jacob Carlborg <doob@me.com> <jacob.carlborg@gmail.com>
date Sat, 09 Aug 2008 17:00:02 +0200
parents
children 649b8e223d5a
comparison
equal deleted inserted replaced
-1:000000000000 0:380af2bdd8e5
1 /*******************************************************************************
2 * Copyright (c) 2000, 2006 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 module dwt.widgets.Canvas;
12
13 import dwt.dwthelper.utils;
14
15
16 import dwt.DWT;
17 import dwt.DWTException;
18 import dwt.graphics.Font;
19 import dwt.graphics.GC;
20 import dwt.graphics.Image;
21 import dwt.graphics.Rectangle;
22 import dwt.internal.cocoa.NSBezierPath;
23 import dwt.internal.cocoa.NSColor;
24 import dwt.internal.cocoa.NSGraphicsContext;
25 import dwt.internal.cocoa.NSPoint;
26 import dwt.internal.cocoa.NSRect;
27 import dwt.internal.cocoa.NSSize;
28 import dwt.internal.cocoa.OS;
29
30 /**
31 * Instances of this class provide a surface for drawing
32 * arbitrary graphics.
33 * <dl>
34 * <dt><b>Styles:</b></dt>
35 * <dd>(none)</dd>
36 * <dt><b>Events:</b></dt>
37 * <dd>(none)</dd>
38 * </dl>
39 * <p>
40 * This class may be subclassed by custom control implementors
41 * who are building controls that are <em>not</em> constructed
42 * from aggregates of other controls. That is, they are either
43 * painted using DWT graphics calls or are handled by native
44 * methods.
45 * </p>
46 *
47 * @see Composite
48 */
49 public class Canvas extends Composite {
50 Caret caret;
51 IME ime;
52
53 Canvas () {
54 /* Do nothing */
55 }
56
57 bool becomeFirstResponder () {
58 if (caret !is null) caret.setFocus ();
59 return super.becomeFirstResponder();
60 }
61
62 bool resignFirstResponder () {
63 if (caret !is null) caret.killFocus ();
64 return super.resignFirstResponder();
65 }
66
67
68 /**
69 * Constructs a new instance of this class given its parent
70 * and a style value describing its behavior and appearance.
71 * <p>
72 * The style value is either one of the style constants defined in
73 * class <code>DWT</code> which is applicable to instances of this
74 * class, or must be built by <em>bitwise OR</em>'ing together
75 * (that is, using the <code>int</code> "|" operator) two or more
76 * of those <code>DWT</code> style constants. The class description
77 * lists the style constants that are applicable to the class.
78 * Style bits are also inherited from superclasses.
79 * </p>
80 *
81 * @param parent a composite control which will be the parent of the new instance (cannot be null)
82 * @param style the style of control to construct
83 *
84 * @exception IllegalArgumentException <ul>
85 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
86 * </ul>
87 * @exception DWTException <ul>
88 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
89 * </ul>
90 *
91 * @see DWT
92 * @see Widget#checkSubclass
93 * @see Widget#getStyle
94 */
95 public Canvas (Composite parent, int style) {
96 super (parent, style);
97 }
98
99 /**
100 * Fills the interior of the rectangle specified by the arguments,
101 * with the receiver's background.
102 *
103 * @param gc the gc where the rectangle is to be filled
104 * @param x the x coordinate of the rectangle to be filled
105 * @param y the y coordinate of the rectangle to be filled
106 * @param width the width of the rectangle to be filled
107 * @param height the height of the rectangle to be filled
108 *
109 * @exception IllegalArgumentException <ul>
110 * <li>ERROR_NULL_ARGUMENT - if the gc is null</li>
111 * <li>ERROR_INVALID_ARGUMENT - if the gc has been disposed</li>
112 * </ul>
113 * @exception DWTException <ul>
114 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
115 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
116 * </ul>
117 *
118 * @since 3.2
119 */
120 public void drawBackground (GC gc, int x, int y, int width, int height) {
121 checkWidget ();
122 if (gc is null) error (DWT.ERROR_NULL_ARGUMENT);
123 if (gc.isDisposed ()) error (DWT.ERROR_INVALID_ARGUMENT);
124 Control control = findBackgroundControl ();
125 if (control !is null) {
126 // control.fillBackground (handle, gc.handle, new Rectangle (x, y, width, height));
127 } else {
128 gc.fillRectangle (x, y, width, height);
129 }
130 }
131
132 void drawRect(int id, NSRect rect) {
133 super.drawRect(id, rect);
134 if (caret is null) return;
135 if (caret.isShowing) {
136 NSGraphicsContext context = NSGraphicsContext.currentContext();
137
138 Image image = caret.image;
139 if (image !is null) {
140 NSRect fromRect = new NSRect ();
141 NSSize size = image.handle.size();
142 fromRect.width = size.width;
143 fromRect.height = size.height;
144 NSPoint point = new NSPoint();
145 point.x = caret.x;
146 point.y = caret.y;
147 image.handle.drawAtPoint(point, rect, OS.NSCompositeXOR, 1);
148 } else {
149 context.saveGraphicsState();
150 context.setCompositingOperation(OS.NSCompositeXOR);
151 NSRect drawRect = new NSRect();
152 drawRect.x = caret.x;
153 drawRect.y = caret.y;
154 drawRect.width = caret.width !is 0 ? caret.width : Caret.DEFAULT_WIDTH;
155 drawRect.height = caret.height;
156 context.setShouldAntialias(false);
157 NSColor color = NSColor.colorWithDeviceRed(1, 1, 1, 1);
158 color.set();
159 NSBezierPath.fillRect(drawRect);
160 context.restoreGraphicsState();
161 }
162 }
163 }
164
165 /**
166 * Returns the caret.
167 * <p>
168 * The caret for the control is automatically hidden
169 * and shown when the control is painted or resized,
170 * when focus is gained or lost and when an the control
171 * is scrolled. To avoid drawing on top of the caret,
172 * the programmer must hide and show the caret when
173 * drawing in the window any other time.
174 * </p>
175 *
176 * @return the caret
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 public Caret getCaret () {
184 checkWidget();
185 return caret;
186 }
187
188 public IME getIME () {
189 checkWidget();
190 return ime;
191 }
192
193 //void redrawWidget (int control, bool children) {
194 // bool isFocus = OS.VERSION < 0x1040 && caret !is null && caret.isFocusCaret ();
195 // if (isFocus) caret.killFocus ();
196 // super.redrawWidget (control, children);
197 // if (isFocus) caret.setFocus ();
198 //}
199 //
200 //void redrawWidget (int control, int x, int y, int width, int height, bool all) {
201 // bool isFocus = OS.VERSION < 0x1040 && caret !is null && caret.isFocusCaret ();
202 // if (isFocus) caret.killFocus ();
203 // super.redrawWidget (control, x, y, width, height, all);
204 // if (isFocus) caret.setFocus ();
205 //}
206
207 void releaseChildren (bool destroy) {
208 if (caret !is null) {
209 caret.release (false);
210 caret = null;
211 }
212 if (ime !is null) {
213 ime.release (false);
214 ime = null;
215 }
216 super.releaseChildren (destroy);
217 }
218
219 /**
220 * Scrolls a rectangular area of the receiver by first copying
221 * the source area to the destination and then causing the area
222 * of the source which is not covered by the destination to
223 * be repainted. Children that intersect the rectangle are
224 * optionally moved during the operation. In addition, outstanding
225 * paint events are flushed before the source area is copied to
226 * ensure that the contents of the canvas are drawn correctly.
227 *
228 * @param destX the x coordinate of the destination
229 * @param destY the y coordinate of the destination
230 * @param x the x coordinate of the source
231 * @param y the y coordinate of the source
232 * @param width the width of the area
233 * @param height the height of the area
234 * @param all <code>true</code>if children should be scrolled, and <code>false</code> otherwise
235 *
236 * @exception DWTException <ul>
237 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
238 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
239 * </ul>
240 */
241 public void scroll (int destX, int destY, int x, int y, int width, int height, bool all) {
242 checkWidget();
243 if (width <= 0 || height <= 0) return;
244 int deltaX = destX - x, deltaY = destY - y;
245 if (deltaX is 0 && deltaY is 0) return;
246 // if (!isDrawing (handle)) return;
247 bool isFocus = caret !is null && caret.isFocusCaret ();
248 if (isFocus) caret.killFocus ();
249 Rectangle clientRect = getClientArea ();
250 Rectangle sourceRect = new Rectangle (x, y, width, height);
251 if (sourceRect.intersects (clientRect)) {
252 update (all);
253 }
254 NSRect damage = new NSRect();
255 damage.x = x;
256 damage.y = y;
257 damage.width = width;
258 damage.height = height;
259 view.setNeedsDisplayInRect(damage);
260 damage.x = destX;
261 damage.y = destY;
262 view.setNeedsDisplayInRect(damage);
263 // Control control = findBackgroundControl ();
264 // if ((control !is null && control.backgroundImage !is null)) {
265 // redrawWidget (handle, x, y, width, height, false);
266 // redrawWidget (handle, destX, destY, width, height, false);
267 // } else {
268 // GC gc = new GC (this);
269 // gc.copyArea (x, y, width, height, destX, destY);
270 // gc.dispose ();
271 // }
272 if (all) {
273 Control [] children = _getChildren ();
274 for (int i=0; i<children.length; i++) {
275 Control child = children [i];
276 Rectangle rect = child.getBounds ();
277 if (Math.min(x + width, rect.x + rect.width) >= Math.max (x, rect.x) &&
278 Math.min(y + height, rect.y + rect.height) >= Math.max (y, rect.y)) {
279 child.setLocation (rect.x + deltaX, rect.y + deltaY);
280 }
281 }
282 }
283 if (isFocus) caret.setFocus ();
284 }
285
286 /**
287 * Sets the receiver's caret.
288 * <p>
289 * The caret for the control is automatically hidden
290 * and shown when the control is painted or resized,
291 * when focus is gained or lost and when an the control
292 * is scrolled. To avoid drawing on top of the caret,
293 * the programmer must hide and show the caret when
294 * drawing in the window any other time.
295 * </p>
296 * @param caret the new caret for the receiver, may be null
297 *
298 * @exception IllegalArgumentException <ul>
299 * <li>ERROR_INVALID_ARGUMENT - if the caret has been disposed</li>
300 * </ul>
301 * @exception DWTException <ul>
302 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
303 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
304 * </ul>
305 */
306 public void setCaret (Caret caret) {
307 checkWidget();
308 Caret newCaret = caret;
309 Caret oldCaret = this.caret;
310 this.caret = newCaret;
311 if (hasFocus ()) {
312 if (oldCaret !is null) oldCaret.killFocus ();
313 if (newCaret !is null) {
314 if (newCaret.isDisposed()) error(DWT.ERROR_INVALID_ARGUMENT);
315 newCaret.setFocus ();
316 }
317 }
318 }
319
320 public void setFont (Font font) {
321 checkWidget ();
322 if (caret !is null) caret.setFont (font);
323 super.setFont (font);
324 }
325
326 public void setIME (IME ime) {
327 checkWidget ();
328 if (ime !is null && ime.isDisposed()) error(DWT.ERROR_INVALID_ARGUMENT);
329 this.ime = ime;
330 }
331
332 }