|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Public abstract class defining the |
|
15 * interface for MIDP Canvas Graphics Item. |
|
16 * |
|
17 */ |
|
18 |
|
19 package com.nokia.mid.ui; |
|
20 |
|
21 import java.util.Enumeration; |
|
22 import javax.microedition.lcdui.Canvas; |
|
23 import javax.microedition.lcdui.CustomItem; |
|
24 import javax.microedition.lcdui.Graphics; |
|
25 |
|
26 import com.nokia.mid.ui.CanvasItem; |
|
27 import com.nokia.mid.ui.CanvasGraphicsItemPainter; |
|
28 |
|
29 import com.nokia.mj.impl.rt.legacy.NativeError; |
|
30 import com.nokia.mj.impl.rt.legacy.ToolkitInvoker; |
|
31 /** |
|
32 * <P> |
|
33 * A <code>CanvasGraphicsItem</code> is a drawable component that is used with a |
|
34 * parent object; with <code>Canvas</code>. The <code>CanvasGraphicsItem</code> |
|
35 * may be added to and removed from <code>Canvas</code> through |
|
36 * <code>setParent</code> method. |
|
37 * </P> |
|
38 * |
|
39 * <P> |
|
40 * Parent for <code>CanvasGraphicsItem</code> must be set, through |
|
41 * <code>setParent</code> method, before other methods are called and change the |
|
42 * state or parameters of <code>CanvasGraphicsItem</code>. |
|
43 * </P> |
|
44 * |
|
45 * <P> |
|
46 * The implementation presents the <code>CanvasGraphicsItem</code> with the same |
|
47 * draw capabilities as <code>Canvas</code> has. See <a |
|
48 * href="Graphics.html">Graphics</a> for drawing options. |
|
49 * </P> |
|
50 * |
|
51 * <P> |
|
52 * <code>CanvasGraphicsItem</code> does not support DSA over its area. Playing |
|
53 * video or using camera over <code>CanvasGraphicsItem</code> area can lead to |
|
54 * artifacts on screen. |
|
55 * </P> |
|
56 * |
|
57 * <P> |
|
58 * <code>CanvasGraphicsItem</code> does not support touch input. Pointer events |
|
59 * are delivered to parent object from the area of the visible |
|
60 * <code>CanvasGraphicsItem</code>. |
|
61 * </P> |
|
62 * |
|
63 * <P> |
|
64 * Visibility of <code>CanvasGraphicsItem</code> is set through |
|
65 * <code>setVisible()</code>. The default visbility is set to false. Changing |
|
66 * parent does not affect the visibility status. |
|
67 * </P> |
|
68 * |
|
69 * <P> |
|
70 * The <code>CanvasGraphicsItem</code> cannot have focus. |
|
71 * </P> |
|
72 * |
|
73 * @since 1.4 |
|
74 */ |
|
75 public abstract class CanvasGraphicsItem |
|
76 extends CanvasItem |
|
77 { |
|
78 // Private data |
|
79 |
|
80 // Native handle |
|
81 int iHandle; |
|
82 |
|
83 // LCDUI Toolkit invoker object. |
|
84 ToolkitInvoker iToolkitInvoker; |
|
85 |
|
86 // LCDUI Toolkit object. |
|
87 Object iToolkit; |
|
88 |
|
89 private com.nokia.mid.ui.CanvasGraphicsItemPainter iItemPainter; |
|
90 |
|
91 /** |
|
92 * Creates a new <code>CanvasGraphicsItem</code> object with the given |
|
93 * initial size. |
|
94 * |
|
95 * @param width |
|
96 * width in pixels |
|
97 * @param height |
|
98 * height in pixels |
|
99 * |
|
100 * @throws IllegalArgumentException |
|
101 * if the width or height is less than one pixel |
|
102 */ |
|
103 public CanvasGraphicsItem(int width, int height) |
|
104 { |
|
105 // Validate width and height. |
|
106 if (!(width >= 1 && height >= 1)) |
|
107 { |
|
108 throw new IllegalArgumentException(ERROR_GIVEN_ARGUMENTS_NOT_VALID); |
|
109 } |
|
110 |
|
111 // Toolkit invoker is needed for accessing javax.microedition.lcdui |
|
112 // package |
|
113 iToolkitInvoker = ToolkitInvoker.getToolkitInvoker(); |
|
114 iToolkit = iToolkitInvoker.getToolkit(); |
|
115 |
|
116 // Create painter |
|
117 iItemPainter = |
|
118 CanvasGraphicsItemPainterInvoker.createCanvasGraphicsItemPainter( |
|
119 this, iToolkit, width, height); |
|
120 |
|
121 int painterHandle = iItemPainter.getHandle(); |
|
122 |
|
123 int handle = 0; |
|
124 |
|
125 synchronized (iToolkit) |
|
126 { |
|
127 // Create native peer object for this Java object. |
|
128 handle = |
|
129 _createNativePeer(getToolkitHandle(), painterHandle, width, |
|
130 height); |
|
131 } |
|
132 |
|
133 // Check if construction failed and throw out of memory error. |
|
134 if (handle <= NativeError.KErrNone) |
|
135 { |
|
136 throw new OutOfMemoryError(); |
|
137 } |
|
138 |
|
139 // Operation was a success, store size. |
|
140 iWidth = width; |
|
141 iHeight = height; |
|
142 |
|
143 // Sets parent to null |
|
144 iParent = null; |
|
145 |
|
146 // Set visibility |
|
147 iVisible = false; |
|
148 |
|
149 // Construction was successful. Store handle and register for |
|
150 // finalization. |
|
151 iHandle = handle; |
|
152 } |
|
153 |
|
154 /** |
|
155 * Set the parent object of this <code>CanvasGraphicsItem</code>. |
|
156 * |
|
157 * Typically the parent object would be Canvas. Setting the parameter to |
|
158 * null removes the association to the parent. If |
|
159 * <code>setParent(null)</code> is called for a |
|
160 * <code>CanvasGraphicsItem</code> yet not having any parent or |
|
161 * <code>setParent(parent)</code> is called with the same parent, the call |
|
162 * is silently ignored. |
|
163 * |
|
164 * @param parent |
|
165 * the parent object |
|
166 * |
|
167 * @throws IllegalArgumentException |
|
168 * if <code>aParent</code> is not a valid object with which a |
|
169 * CanvasGraphicsItem can be associated, or if CanvasItem |
|
170 * is already set to another another parent |
|
171 */ |
|
172 public void setParent(java.lang.Object parent) |
|
173 { |
|
174 // Ignore argument check if parent is set to null. |
|
175 // Custom item support will be added in future, currently it's |
|
176 // unsupported. |
|
177 if (((parent != null) && !(parent instanceof Canvas)) || |
|
178 ((parent != null) && (iParent != null) && (iParent != parent))) |
|
179 { |
|
180 throw new IllegalArgumentException(ERROR_NOT_A_VALID_PARENT_OBJECT); |
|
181 } |
|
182 |
|
183 if (parent != iParent) |
|
184 { |
|
185 // Lock this object so that parent cannot be adjusted from other |
|
186 // threads. |
|
187 synchronized (iToolkit) |
|
188 { |
|
189 int parentHandle = 0; |
|
190 |
|
191 // Toolkit invoker can be used to get proper handles. |
|
192 if (parent instanceof Canvas) |
|
193 { |
|
194 // Note that canvas is shown inside a displayable so in this |
|
195 // case we use the handle to the displayble object. |
|
196 parentHandle = iToolkitInvoker.getDisplayableHandle(parent); |
|
197 } |
|
198 else if (parent instanceof CustomItem) |
|
199 { |
|
200 parentHandle = iToolkitInvoker.itemGetHandle(parent); |
|
201 } |
|
202 |
|
203 // parentHandle = 0 indicates removal of the parent. |
|
204 int error = |
|
205 _setParent(getToolkitHandle(), iHandle, parentHandle); |
|
206 |
|
207 // Check if an error occured when setting the parent object. |
|
208 NativeError.check(error); |
|
209 |
|
210 // Store new parent |
|
211 iParent = parent; |
|
212 } |
|
213 } |
|
214 } |
|
215 |
|
216 /** |
|
217 * Sets the size of this <code>CanvasGraphicsItem</code> in pixels. |
|
218 * |
|
219 * @param width |
|
220 * width in pixels |
|
221 * @param height |
|
222 * height in pixels |
|
223 * |
|
224 * @throws IllegalArgumentException |
|
225 * if the width or height is less than one pixel |
|
226 */ |
|
227 public void setSize(int width, int height) |
|
228 { |
|
229 // Validate width and row count |
|
230 if (width < 1 || height < 1) |
|
231 { |
|
232 throw new IllegalArgumentException(ERROR_GIVEN_ARGUMENTS_NOT_VALID); |
|
233 } |
|
234 |
|
235 synchronized (iToolkit) |
|
236 { |
|
237 NativeError.check(_setSize(getToolkitHandle(), iHandle, width, |
|
238 height)); |
|
239 |
|
240 // Operation was a success, store size. |
|
241 iWidth = width; |
|
242 iHeight = height; |
|
243 } |
|
244 } |
|
245 |
|
246 /** |
|
247 * <P> |
|
248 * Sets the rendering position of this <code>CanvasGraphicsItem</code>. The |
|
249 * anchor point given is relative to the upper left corner of the target |
|
250 * <code>Canvas</code>. |
|
251 * </P> |
|
252 * |
|
253 * <P> |
|
254 * The <code>CanvasGraphicsItem</code> may be placed fully off or partially |
|
255 * of the visible area of the target <code>Canvas</code> by the |
|
256 * <code>setPosition</code> method; in this case the |
|
257 * <code>CanvasGraphicsItem</code> is just parly visible. |
|
258 * </P> |
|
259 * |
|
260 * @param x |
|
261 * the x coordinate of the anchor point, in pixels. |
|
262 * @param y |
|
263 * the y coordinate of the anchor point, in pixels. |
|
264 * |
|
265 * @throws IllegalStateException |
|
266 * if a valid parent object hasn't been set. |
|
267 * |
|
268 * @see #setParent(java.lang.Object aParent) |
|
269 */ |
|
270 public void setPosition(int x, int y) |
|
271 { |
|
272 synchronized (iToolkit) |
|
273 { |
|
274 checkParent(); |
|
275 |
|
276 NativeError.check(_setPosition(getToolkitHandle(), iHandle, x, y)); |
|
277 |
|
278 // Store current position. |
|
279 iPositionX = x; |
|
280 iPositionY = y; |
|
281 } |
|
282 } |
|
283 |
|
284 /** |
|
285 * <P> |
|
286 * Sets the visibility value of <code>CanvasGraphicsItem</code>. Initially |
|
287 * <code>CanvasGraphicsItem</code> is not visible so it must be explicitly |
|
288 * set to visible in order it to appear on UI. |
|
289 * </P> |
|
290 * |
|
291 * <P> |
|
292 * Setting visibility to true shows the graphics item with its content. If |
|
293 * the graphics item is already visible calling |
|
294 * <code>setVisible(true)</code> does nothing. |
|
295 * </P> |
|
296 * |
|
297 * <P> |
|
298 * Setting the visibility to false hides the graphics item and its content. |
|
299 * If the graphics item is already hidden calling |
|
300 * <code>setVisible(false)</code> does nothing. |
|
301 * </P> |
|
302 * |
|
303 * @param visible |
|
304 * visibility of the <code>CanvasGraphicsItem</code> |
|
305 * |
|
306 * @throws IllegalStateException |
|
307 * if a valid parent object has not been set. |
|
308 * |
|
309 * @see #setParent(java.lang.Object aParent) |
|
310 */ |
|
311 public void setVisible(boolean visible) |
|
312 { |
|
313 synchronized (iToolkit) |
|
314 { |
|
315 checkParent(); |
|
316 |
|
317 NativeError |
|
318 .check(_setVisible(getToolkitHandle(), iHandle, visible)); |
|
319 |
|
320 iVisible = visible; |
|
321 } |
|
322 } |
|
323 |
|
324 /** |
|
325 * <P> |
|
326 * Sets the Z-position (elevation) of the item. |
|
327 * <p> |
|
328 * The Z-position decides the stacking order of items on the same parent. An |
|
329 * item of higher Z-position will be drawn on top of an item with a lower |
|
330 * Z-position. |
|
331 * <p> |
|
332 * The Z-position is unique for each item, meaning that changing a |
|
333 * Z-position of an item may change the Z-position of the items that share |
|
334 * the same parent. The Z-position does not affect the item's size in any |
|
335 * way. |
|
336 * <p> |
|
337 * When items are added with {@link CanvasItem#setParent} they will get a |
|
338 * Z-position that is increased by 1 from the item that is the top most item |
|
339 * at that time. |
|
340 * </P> |
|
341 * |
|
342 * @param z |
|
343 * the Z-position of the item. |
|
344 * |
|
345 * @throws IllegalArgumentException |
|
346 * if <code>z</code> < 0 |
|
347 * @throws IllegalStateException |
|
348 * if a valid parent object has not been set. |
|
349 * |
|
350 * @see #getZPosition() |
|
351 * @see #setParent(java.lang.Object aParent) |
|
352 */ |
|
353 public void setZPosition(int z) |
|
354 { |
|
355 if (z < 0) |
|
356 { |
|
357 throw new IllegalArgumentException(); |
|
358 } |
|
359 |
|
360 synchronized (iToolkit) |
|
361 { |
|
362 checkParent(); |
|
363 |
|
364 NativeError.check(_setZPosition(getToolkitHandle(), iHandle, z)); |
|
365 } |
|
366 } |
|
367 |
|
368 /** |
|
369 * <P> |
|
370 * Returns the Z-position (elevation) of the item. |
|
371 * |
|
372 * @see #setZPosition(int) </P> |
|
373 * |
|
374 * @throws IllegalStateException |
|
375 * if a valid parent object has not been set. |
|
376 * |
|
377 * @see #setParent(java.lang.Object aParent) |
|
378 */ |
|
379 public int getZPosition() |
|
380 { |
|
381 int positionZ = -1; |
|
382 |
|
383 synchronized (iToolkit) |
|
384 { |
|
385 checkParent(); |
|
386 |
|
387 positionZ = _getZPosition(getToolkitHandle(), iHandle); |
|
388 } |
|
389 |
|
390 NativeError.check(positionZ); |
|
391 |
|
392 return positionZ; |
|
393 } |
|
394 |
|
395 /* |
|
396 * Hidden default constructor. |
|
397 */ |
|
398 CanvasGraphicsItem() |
|
399 { |
|
400 } |
|
401 |
|
402 /** |
|
403 * <P> |
|
404 * Renders the <code>CanvasGraphicsItem</code>. |
|
405 * <P> |
|
406 * The application implements this method to paint graphics on |
|
407 * <code>CanvasGraphicsItem</code>. |
|
408 * <P> |
|
409 * <code>CanvasGraphicsItem</code> paint works in the same way as |
|
410 * <code>Canvas</code> paint method. The only difference to |
|
411 * <code>Canvas</code> paint method is that application does not need to |
|
412 * paint all the pixels of the clip region as that the clip region needing |
|
413 * updating is cleared and fully transparent before paint is called. Content |
|
414 * rendered by application in previous paint method calls is not available |
|
415 * in the clip region. Coordinates used in <code>Graphics</code> methods are |
|
416 * relative to <code>CanvasGraphicsItem</code> itself. This means (0,0) |
|
417 * coordinate is top left pixel of <code>CanvasGraphicsItem</code> as |
|
418 * positioned in the containing parent (e.g. <code>Canvas</code>). |
|
419 * </P> |
|
420 * |
|
421 * @param graphics |
|
422 * the <code>Graphics</code> object to be used for rendering the |
|
423 * <code>Canvas</code> |
|
424 * |
|
425 */ |
|
426 protected abstract void paint(javax.microedition.lcdui.Graphics graphics); |
|
427 |
|
428 /** |
|
429 * Requests a repaint for the specified region of the |
|
430 * <code>CanvasGraphicsItem</code>. |
|
431 * <P> |
|
432 * Coordinates are relative to the <code>CanvasGraphicsItem</code> |
|
433 * coordinates. The method works in similar manner as <code>Canvas</code> |
|
434 * repaint method. |
|
435 * |
|
436 * @param x |
|
437 * the x coordinate of the rectangle to be repainted, in pixels |
|
438 * @param y |
|
439 * the y coordinate of the rectangle to be repainted, in pixels |
|
440 * @param width |
|
441 * the width of the rectangle to be repainted, in pixels |
|
442 * @param height |
|
443 * the height of the rectangle to be repainted, in pixels |
|
444 * |
|
445 */ |
|
446 public final void repaint(int x, int y, int width, int height) |
|
447 { |
|
448 iItemPainter.Repaint(x, y, width, height); |
|
449 } |
|
450 |
|
451 /** |
|
452 * Requests a repaint for the entire <code>CanvasGraphicsItem</code>. The |
|
453 * effect is identical to |
|
454 * <code>repaint(0, 0, getWidth(), getHeight());</code> |
|
455 * |
|
456 * @see #repaint(int x, int y, int width, int height) |
|
457 */ |
|
458 public final void repaint() |
|
459 { |
|
460 iItemPainter.Repaint(0, 0, getWidth(), getHeight()); |
|
461 } |
|
462 |
|
463 void Repaint(Graphics aGraphics) |
|
464 { |
|
465 paint(aGraphics); |
|
466 } |
|
467 |
|
468 /* |
|
469 * Returns the native side handle to the LCDUI Toolkit. |
|
470 * |
|
471 * @return The native side handle to the LCDUI Toolkit. |
|
472 */ |
|
473 synchronized int getToolkitHandle() |
|
474 { |
|
475 return iToolkitInvoker.toolkitGetHandle(iToolkit); |
|
476 } |
|
477 |
|
478 // Native methods |
|
479 |
|
480 /* |
|
481 * Creates the native side peer object for this CanvasGraphicsItem. |
|
482 * |
|
483 * @param aToolkitHandle A handle to the LCDUI toolkit. |
|
484 * |
|
485 * @param aPainterHandle A handle of a CanvasGraphicsItemPainter native side |
|
486 * peer |
|
487 * |
|
488 * @param width The new width of this canvas graphics item. |
|
489 * |
|
490 * @param height The new hight of this canvas graphics item. |
|
491 * |
|
492 * @return A handle to the the native side peer object or a system-wide |
|
493 * error code. |
|
494 */ |
|
495 private native int _createNativePeer( |
|
496 int aToolkitHandle, |
|
497 int aPainterHandle, |
|
498 int width, |
|
499 int height); |
|
500 |
|
501 /* |
|
502 * Disposes the native side peer object. |
|
503 * |
|
504 * @param aToolkitHandle A handle to the LCDUI toolkit. |
|
505 * |
|
506 * @param aNativePeerHandle A handle to the native side peer object. |
|
507 */ |
|
508 private native void _dispose(int aToolkitHandle, int aNativePeerHandle); |
|
509 |
|
510 /* |
|
511 * Sets the size of this graphics item using the given width and height. |
|
512 * |
|
513 * @param aToolkitHandle A handle to the LCDUI toolkit. |
|
514 * |
|
515 * @param aNativePeerHandle A handle to the native side peer object. |
|
516 * |
|
517 * @param width The new width of this graphics item. |
|
518 * |
|
519 * @param height The new hight of this graphics item. |
|
520 * |
|
521 * @return NativeError.KErrNone if the operation was successful. Otherwise, |
|
522 * a system-wide error code is returned. |
|
523 */ |
|
524 private native int _setSize( |
|
525 int aToolkitHandle, |
|
526 int aNativePeerHandle, |
|
527 int width, |
|
528 int height); |
|
529 |
|
530 /* |
|
531 * Disposes the native side peer object. |
|
532 * |
|
533 * @param aToolkitHandle A handle to the LCDUI toolkit. |
|
534 * |
|
535 * @param aNativePeerHandle A handle to the native side peer object. |
|
536 * |
|
537 * @param aParentHandle A handle to the parent object. |
|
538 * |
|
539 * @return NativeError.KErrNone if the operation was successful. Otherwise, |
|
540 * a system-wide error code is returned. |
|
541 */ |
|
542 private native int _setParent( |
|
543 int aToolkitHandle, |
|
544 int aNativePeerHandle, |
|
545 int aParentHandle); |
|
546 |
|
547 /* |
|
548 * Sets the graphics item visible. |
|
549 * |
|
550 * @param aToolkitHandle A handle to the LCDUI toolkit. |
|
551 * |
|
552 * @param aNativePeerHandle A handle to the native side peer object. |
|
553 * |
|
554 * @param aVisible The visibility status of this graphics item. |
|
555 * |
|
556 * @return NativeError.KErrNone if the operation was successful. Otherwise, |
|
557 * a system-wide error code is returned. |
|
558 */ |
|
559 private native int _setVisible( |
|
560 int aToolkitHandle, |
|
561 int aNativePeerHandle, |
|
562 boolean aVisible); |
|
563 |
|
564 /* |
|
565 * Sets the graphics item's position. |
|
566 * |
|
567 * @param aToolkitHandle A handle to the LCDUI toolkit. |
|
568 * |
|
569 * @param aNativePeerHandle A handle to the native side peer object. |
|
570 * |
|
571 * @param x The x coordinate of the anchor point. |
|
572 * |
|
573 * @param y The y coordinate of the anchor point. |
|
574 * |
|
575 * @return NativeError.KErrNone if the operation was successful. Otherwise, |
|
576 * a system-wide error code is returned. |
|
577 */ |
|
578 private native int _setPosition( |
|
579 int aToolkitHandle, |
|
580 int aNativePeerHandle, |
|
581 int x, |
|
582 int y); |
|
583 |
|
584 /* |
|
585 * Sets the elevation of this graphics item. |
|
586 * |
|
587 * @param aToolkitHandle A handle to the LCDUI toolkit. |
|
588 * |
|
589 * @param aNativePeerHandle A handle to the native side peer object. |
|
590 * |
|
591 * @param aZ The new z-position. |
|
592 * |
|
593 * @return NativeError.KErrNone if the operation was successful. Otherwise, |
|
594 * a system-wide error code is returned. |
|
595 */ |
|
596 private native int _setZPosition( |
|
597 int aToolkitHandle, |
|
598 int aNativePeerHandle, |
|
599 int aZ); |
|
600 |
|
601 /* |
|
602 * Gets the elevation of this graphics item. |
|
603 * |
|
604 * @param aToolkitHandle A handle to the LCDUI toolkit. |
|
605 * |
|
606 * @param aNativePeerHandle A handle to the native side peer object. |
|
607 * |
|
608 * @return The elevation if the operation was successful. Otherwise, a |
|
609 * system-wide error code is returned. |
|
610 */ |
|
611 private native int _getZPosition(int aToolkitHandle, int aNativePeerHandle); |
|
612 } |