PageRenderTime 61ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

/swt4ruby/src/linux-x86_32/org/eclipse/swt/widgets/Canvas.java

https://github.com/neelance/swt4ruby
Java | 407 lines | 213 code | 24 blank | 170 comment | 89 complexity | 6e7e77e972536d07c723608777f8d1b6 MD5 | raw file
Possible License(s): EPL-1.0
  1. /*******************************************************************************
  2. * Copyright (c) 2000, 2008 IBM Corporation and others.
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * http://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors:
  9. * IBM Corporation - initial API and implementation
  10. *******************************************************************************/
  11. package org.eclipse.swt.widgets;
  12. import org.eclipse.swt.graphics.*;
  13. import org.eclipse.swt.internal.gtk.*;
  14. import org.eclipse.swt.*;
  15. /**
  16. * Instances of this class provide a surface for drawing
  17. * arbitrary graphics.
  18. * <dl>
  19. * <dt><b>Styles:</b></dt>
  20. * <dd>(none)</dd>
  21. * <dt><b>Events:</b></dt>
  22. * <dd>(none)</dd>
  23. * </dl>
  24. * <p>
  25. * This class may be subclassed by custom control implementors
  26. * who are building controls that are <em>not</em> constructed
  27. * from aggregates of other controls. That is, they are either
  28. * painted using SWT graphics calls or are handled by native
  29. * methods.
  30. * </p>
  31. *
  32. * @see Composite
  33. * @see <a href="http://www.eclipse.org/swt/snippets/#canvas">Canvas snippets</a>
  34. * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: ControlExample</a>
  35. * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
  36. */
  37. public class Canvas extends Composite {
  38. Caret caret;
  39. IME ime;
  40. Canvas () {}
  41. /**
  42. * Constructs a new instance of this class given its parent
  43. * and a style value describing its behavior and appearance.
  44. * <p>
  45. * The style value is either one of the style constants defined in
  46. * class <code>SWT</code> which is applicable to instances of this
  47. * class, or must be built by <em>bitwise OR</em>'ing together
  48. * (that is, using the <code>int</code> "|" operator) two or more
  49. * of those <code>SWT</code> style constants. The class description
  50. * lists the style constants that are applicable to the class.
  51. * Style bits are also inherited from superclasses.
  52. * </p>
  53. *
  54. * @param parent a composite control which will be the parent of the new instance (cannot be null)
  55. * @param style the style of control to construct
  56. *
  57. * @exception IllegalArgumentException <ul>
  58. * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
  59. * </ul>
  60. * @exception SWTException <ul>
  61. * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
  62. * </ul>
  63. *
  64. * @see SWT
  65. * @see Widget#checkSubclass
  66. * @see Widget#getStyle
  67. */
  68. public Canvas (Composite parent, int style) {
  69. super (parent, checkStyle (style));
  70. }
  71. /**
  72. * Fills the interior of the rectangle specified by the arguments,
  73. * with the receiver's background.
  74. *
  75. * @param gc the gc where the rectangle is to be filled
  76. * @param x the x coordinate of the rectangle to be filled
  77. * @param y the y coordinate of the rectangle to be filled
  78. * @param width the width of the rectangle to be filled
  79. * @param height the height of the rectangle to be filled
  80. *
  81. * @exception IllegalArgumentException <ul>
  82. * <li>ERROR_NULL_ARGUMENT - if the gc is null</li>
  83. * <li>ERROR_INVALID_ARGUMENT - if the gc has been disposed</li>
  84. * </ul>
  85. * @exception SWTException <ul>
  86. * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
  87. * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
  88. * </ul>
  89. *
  90. * @since 3.2
  91. */
  92. public void drawBackground (GC gc, int x, int y, int width, int height) {
  93. checkWidget ();
  94. if (gc == null) error (SWT.ERROR_NULL_ARGUMENT);
  95. if (gc.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
  96. super.drawBackground (gc, x, y, width, height);
  97. }
  98. /**
  99. * Returns the caret.
  100. * <p>
  101. * The caret for the control is automatically hidden
  102. * and shown when the control is painted or resized,
  103. * when focus is gained or lost and when an the control
  104. * is scrolled. To avoid drawing on top of the caret,
  105. * the programmer must hide and show the caret when
  106. * drawing in the window any other time.
  107. * </p>
  108. *
  109. * @return the caret for the receiver, may be null
  110. *
  111. * @exception SWTException <ul>
  112. * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
  113. * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
  114. * </ul>
  115. */
  116. public Caret getCaret () {
  117. checkWidget();
  118. return caret;
  119. }
  120. Point getIMCaretPos () {
  121. if (caret == null) return super.getIMCaretPos ();
  122. return new Point (caret.x, caret.y);
  123. }
  124. /**
  125. * Returns the IME.
  126. *
  127. * @return the IME
  128. *
  129. * @exception SWTException <ul>
  130. * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
  131. * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
  132. * </ul>
  133. *
  134. * @since 3.4
  135. */
  136. public IME getIME () {
  137. checkWidget ();
  138. return ime;
  139. }
  140. int /*long*/ gtk_button_press_event (int /*long*/ widget, int /*long*/ event) {
  141. if (ime != null) {
  142. int /*long*/ result = ime.gtk_button_press_event (widget, event);
  143. if (result != 0) return result;
  144. }
  145. return super.gtk_button_press_event (widget, event);
  146. }
  147. int /*long*/ gtk_commit (int /*long*/ imcontext, int /*long*/ text) {
  148. if (ime != null) {
  149. int /*long*/ result = ime.gtk_commit (imcontext, text);
  150. if (result != 0) return result;
  151. }
  152. return super.gtk_commit (imcontext, text);
  153. }
  154. int /*long*/ gtk_expose_event (int /*long*/ widget, int /*long*/ event) {
  155. if ((state & OBSCURED) != 0) return 0;
  156. boolean isFocus = caret != null && caret.isFocusCaret ();
  157. if (isFocus) caret.killFocus ();
  158. int /*long*/ result = super.gtk_expose_event (widget, event);
  159. if (isFocus) caret.setFocus ();
  160. return result;
  161. }
  162. int /*long*/ gtk_focus_in_event (int /*long*/ widget, int /*long*/ event) {
  163. int /*long*/ result = super.gtk_focus_in_event (widget, event);
  164. if (caret != null) caret.setFocus ();
  165. return result;
  166. }
  167. int /*long*/ gtk_focus_out_event (int /*long*/ widget, int /*long*/ event) {
  168. int /*long*/ result = super.gtk_focus_out_event (widget, event);
  169. if (caret != null) caret.killFocus ();
  170. return result;
  171. }
  172. int /*long*/ gtk_preedit_changed (int /*long*/ imcontext) {
  173. if (ime != null) {
  174. int /*long*/ result = ime.gtk_preedit_changed (imcontext);
  175. if (result != 0) return result;
  176. }
  177. return super.gtk_preedit_changed (imcontext);
  178. }
  179. void redrawWidget (int x, int y, int width, int height, boolean redrawAll, boolean all, boolean trim) {
  180. boolean isFocus = caret != null && caret.isFocusCaret ();
  181. if (isFocus) caret.killFocus ();
  182. super.redrawWidget (x, y, width, height, redrawAll, all, trim);
  183. if (isFocus) caret.setFocus ();
  184. }
  185. void releaseChildren (boolean destroy) {
  186. if (caret != null) {
  187. caret.release (false);
  188. caret = null;
  189. }
  190. if (ime != null) {
  191. ime.release (false);
  192. ime = null;
  193. }
  194. super.releaseChildren (destroy);
  195. }
  196. /**
  197. * Scrolls a rectangular area of the receiver by first copying
  198. * the source area to the destination and then causing the area
  199. * of the source which is not covered by the destination to
  200. * be repainted. Children that intersect the rectangle are
  201. * optionally moved during the operation. In addition, outstanding
  202. * paint events are flushed before the source area is copied to
  203. * ensure that the contents of the canvas are drawn correctly.
  204. *
  205. * @param destX the x coordinate of the destination
  206. * @param destY the y coordinate of the destination
  207. * @param x the x coordinate of the source
  208. * @param y the y coordinate of the source
  209. * @param width the width of the area
  210. * @param height the height of the area
  211. * @param all <code>true</code>if children should be scrolled, and <code>false</code> otherwise
  212. *
  213. * @exception SWTException <ul>
  214. * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
  215. * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
  216. * </ul>
  217. */
  218. public void scroll (int destX, int destY, int x, int y, int width, int height, boolean all) {
  219. checkWidget();
  220. if (width <= 0 || height <= 0) return;
  221. if ((style & SWT.MIRRORED) != 0) {
  222. int clientWidth = getClientWidth ();
  223. x = clientWidth - width - x;
  224. destX = clientWidth - width - destX;
  225. }
  226. int deltaX = destX - x, deltaY = destY - y;
  227. if (deltaX == 0 && deltaY == 0) return;
  228. if (!isVisible ()) return;
  229. boolean isFocus = caret != null && caret.isFocusCaret ();
  230. if (isFocus) caret.killFocus ();
  231. int /*long*/ window = paintWindow ();
  232. int /*long*/ visibleRegion = OS.gdk_drawable_get_visible_region (window);
  233. GdkRectangle srcRect = new GdkRectangle ();
  234. srcRect.x = x;
  235. srcRect.y = y;
  236. srcRect.width = width;
  237. srcRect.height = height;
  238. int /*long*/ copyRegion = OS.gdk_region_rectangle (srcRect);
  239. OS.gdk_region_intersect(copyRegion, visibleRegion);
  240. int /*long*/ invalidateRegion = OS.gdk_region_rectangle (srcRect);
  241. OS.gdk_region_subtract (invalidateRegion, visibleRegion);
  242. OS.gdk_region_offset (invalidateRegion, deltaX, deltaY);
  243. GdkRectangle copyRect = new GdkRectangle();
  244. OS.gdk_region_get_clipbox (copyRegion, copyRect);
  245. if (copyRect.width != 0 && copyRect.height != 0) {
  246. update ();
  247. }
  248. Control control = findBackgroundControl ();
  249. if (control == null) control = this;
  250. if (control.backgroundImage != null) {
  251. redrawWidget (x, y, width, height, false, false, false);
  252. redrawWidget (destX, destY, width, height, false, false, false);
  253. } else {
  254. // GC gc = new GC (this);
  255. // gc.copyArea (x, y, width, height, destX, destY);
  256. // gc.dispose ();
  257. int /*long*/ gdkGC = OS.gdk_gc_new (window);
  258. OS.gdk_gc_set_exposures (gdkGC, true);
  259. OS.gdk_draw_drawable (window, gdkGC, window, copyRect.x, copyRect.y, copyRect.x + deltaX, copyRect.y + deltaY, copyRect.width, copyRect.height);
  260. OS.g_object_unref (gdkGC);
  261. boolean disjoint = (destX + width < x) || (x + width < destX) || (destY + height < y) || (y + height < destY);
  262. if (disjoint) {
  263. GdkRectangle rect = new GdkRectangle ();
  264. rect.x = x;
  265. rect.y = y;
  266. rect.width = width;
  267. rect.height = height;
  268. OS.gdk_region_union_with_rect (invalidateRegion, rect);
  269. } else {
  270. GdkRectangle rect = new GdkRectangle ();
  271. if (deltaX != 0) {
  272. int newX = destX - deltaX;
  273. if (deltaX < 0) newX = destX + width;
  274. rect.x = newX;
  275. rect.y = y;
  276. rect.width = Math.abs(deltaX);
  277. rect.height = height;
  278. OS.gdk_region_union_with_rect (invalidateRegion, rect);
  279. }
  280. if (deltaY != 0) {
  281. int newY = destY - deltaY;
  282. if (deltaY < 0) newY = destY + height;
  283. rect.x = x;
  284. rect.y = newY;
  285. rect.width = width;
  286. rect.height = Math.abs(deltaY);
  287. OS.gdk_region_union_with_rect (invalidateRegion, rect);
  288. }
  289. }
  290. OS.gdk_window_invalidate_region(window, invalidateRegion, all);
  291. OS.gdk_region_destroy (visibleRegion);
  292. OS.gdk_region_destroy (copyRegion);
  293. OS.gdk_region_destroy (invalidateRegion);
  294. }
  295. if (all) {
  296. Control [] children = _getChildren ();
  297. for (int i=0; i<children.length; i++) {
  298. Control child = children [i];
  299. Rectangle rect = child.getBounds ();
  300. if (Math.min(x + width, rect.x + rect.width) >= Math.max (x, rect.x) &&
  301. Math.min(y + height, rect.y + rect.height) >= Math.max (y, rect.y)) {
  302. child.setLocation (rect.x + deltaX, rect.y + deltaY);
  303. }
  304. }
  305. }
  306. if (isFocus) caret.setFocus ();
  307. }
  308. int setBounds (int x, int y, int width, int height, boolean move, boolean resize) {
  309. boolean isFocus = caret != null && caret.isFocusCaret ();
  310. if (isFocus) caret.killFocus ();
  311. int result = super.setBounds (x, y, width, height, move, resize);
  312. if (isFocus) caret.setFocus ();
  313. return result;
  314. }
  315. /**
  316. * Sets the receiver's caret.
  317. * <p>
  318. * The caret for the control is automatically hidden
  319. * and shown when the control is painted or resized,
  320. * when focus is gained or lost and when an the control
  321. * is scrolled. To avoid drawing on top of the caret,
  322. * the programmer must hide and show the caret when
  323. * drawing in the window any other time.
  324. * </p>
  325. * @param caret the new caret for the receiver, may be null
  326. *
  327. * @exception IllegalArgumentException <ul>
  328. * <li>ERROR_INVALID_ARGUMENT - if the caret has been disposed</li>
  329. * </ul>
  330. * @exception SWTException <ul>
  331. * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
  332. * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
  333. * </ul>
  334. */
  335. public void setCaret (Caret caret) {
  336. checkWidget();
  337. Caret newCaret = caret;
  338. Caret oldCaret = this.caret;
  339. this.caret = newCaret;
  340. if (hasFocus ()) {
  341. if (oldCaret != null) oldCaret.killFocus ();
  342. if (newCaret != null) {
  343. if (newCaret.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
  344. newCaret.setFocus ();
  345. }
  346. }
  347. }
  348. public void setFont (Font font) {
  349. checkWidget();
  350. if (caret != null) caret.setFont (font);
  351. super.setFont (font);
  352. }
  353. /**
  354. * Sets the receiver's IME.
  355. *
  356. * @param ime the new IME for the receiver, may be null
  357. *
  358. * @exception IllegalArgumentException <ul>
  359. * <li>ERROR_INVALID_ARGUMENT - if the IME has been disposed</li>
  360. * </ul>
  361. * @exception SWTException <ul>
  362. * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
  363. * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
  364. * </ul>
  365. *
  366. * @since 3.4
  367. */
  368. public void setIME (IME ime) {
  369. checkWidget ();
  370. if (ime != null && ime.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
  371. this.ime = ime;
  372. }
  373. void updateCaret () {
  374. int /*long*/ imHandle = imHandle ();
  375. if (imHandle == 0) return;
  376. GdkRectangle rect = new GdkRectangle ();
  377. rect.x = caret.x;
  378. rect.y = caret.y;
  379. rect.width = caret.width;
  380. rect.height = caret.height;
  381. OS.gtk_im_context_set_cursor_location (imHandle, rect);
  382. }
  383. }