Mercurial > projects > dwt-linux
annotate dwt/widgets/IME.d @ 261:edcf78db8722
fix compile errors for SWT 3.4
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Thu, 03 Jul 2008 21:20:33 +0200 |
parents | c0d810de7093 |
children |
rev | line source |
---|---|
240 | 1 /******************************************************************************* |
259 | 2 * Copyright (c) 2007, 2008 IBM Corporation and others. |
240 | 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.IME; | |
12 | |
261
edcf78db8722
fix compile errors for SWT 3.4
Frank Benoit <benoit@tionex.de>
parents:
259
diff
changeset
|
13 import dwt.dwthelper.utils; |
240 | 14 |
15 import dwt.DWT; | |
259 | 16 import dwt.DWTException; |
240 | 17 import dwt.graphics.Color; |
18 import dwt.graphics.TextStyle; | |
19 import dwt.internal.Converter; | |
20 import dwt.internal.gtk.OS; | |
21 | |
22 import dwt.widgets.Widget; | |
23 import dwt.widgets.Canvas; | |
24 import dwt.widgets.Event; | |
25 | |
259 | 26 /** |
27 * Instances of this class represent input method editors. | |
28 * These are typically in-line pre-edit text areas that allow | |
29 * the user to compose characters from Far Eastern languages | |
30 * such as Japanese, Chinese or Korean. | |
261
edcf78db8722
fix compile errors for SWT 3.4
Frank Benoit <benoit@tionex.de>
parents:
259
diff
changeset
|
31 * |
259 | 32 * <dl> |
33 * <dt><b>Styles:</b></dt> | |
34 * <dd>(none)</dd> | |
35 * <dt><b>Events:</b></dt> | |
36 * <dd>ImeComposition</dd> | |
37 * </dl> | |
38 * <p> | |
39 * IMPORTANT: This class is <em>not</em> intended to be subclassed. | |
40 * </p> | |
261
edcf78db8722
fix compile errors for SWT 3.4
Frank Benoit <benoit@tionex.de>
parents:
259
diff
changeset
|
41 * |
259 | 42 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> |
261
edcf78db8722
fix compile errors for SWT 3.4
Frank Benoit <benoit@tionex.de>
parents:
259
diff
changeset
|
43 * |
259 | 44 * @since 3.4 |
45 */ | |
240 | 46 public class IME : Widget { |
47 Canvas parent; | |
48 int caretOffset; | |
49 int startOffset; | |
50 int commitCount; | |
51 String text; | |
52 int [] ranges; | |
53 TextStyle [] styles; | |
54 bool inComposition; | |
55 | |
56 /** | |
57 * Prevents uninitialized instances from being created outside the package. | |
58 */ | |
59 this () { | |
60 } | |
61 | |
62 /** | |
259 | 63 * Constructs a new instance of this class given its parent |
64 * and a style value describing its behavior and appearance. | |
65 * <p> | |
66 * The style value is either one of the style constants defined in | |
67 * class <code>DWT</code> which is applicable to instances of this | |
261
edcf78db8722
fix compile errors for SWT 3.4
Frank Benoit <benoit@tionex.de>
parents:
259
diff
changeset
|
68 * class, or must be built by <em>bitwise OR</em>'ing together |
259 | 69 * (that is, using the <code>int</code> "|" operator) two or more |
70 * of those <code>DWT</code> style constants. The class description | |
71 * lists the style constants that are applicable to the class. | |
72 * Style bits are also inherited from superclasses. | |
73 * </p> | |
240 | 74 * |
259 | 75 * @param parent a canvas control which will be the parent of the new instance (cannot be null) |
76 * @param style the style of control to construct | |
77 * | |
78 * @exception IllegalArgumentException <ul> | |
79 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
80 * </ul> | |
81 * @exception DWTException <ul> | |
82 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> | |
83 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | |
84 * </ul> | |
85 * | |
86 * @see Widget#checkSubclass | |
87 * @see Widget#getStyle | |
240 | 88 */ |
89 public this (Canvas parent, int style) { | |
90 super (parent, style); | |
91 this.parent = parent; | |
92 createWidget (); | |
93 } | |
94 | |
95 void createWidget () { | |
96 text = ""; | |
97 startOffset = -1; | |
98 if (parent.getIME () is null) { | |
99 parent.setIME (this); | |
100 } | |
101 } | |
102 | |
259 | 103 /** |
104 * Returns the offset of the caret from the start of the document. | |
105 * The caret is within the current composition. | |
106 * | |
107 * @return the caret offset | |
108 * | |
109 * @exception DWTException <ul> | |
110 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
111 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
112 * </ul> | |
113 */ | |
240 | 114 public int getCaretOffset () { |
115 checkWidget (); | |
116 return startOffset + caretOffset; | |
117 } | |
118 | |
259 | 119 /** |
120 * Returns the commit count of the composition. This is the | |
121 * number of characters that have been composed. When the | |
122 * commit count is equal to the length of the composition | |
123 * text, then the in-line edit operation is complete. | |
261
edcf78db8722
fix compile errors for SWT 3.4
Frank Benoit <benoit@tionex.de>
parents:
259
diff
changeset
|
124 * |
259 | 125 * @return the commit count |
126 * | |
127 * @exception DWTException <ul> | |
128 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
129 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
130 * </ul> | |
261
edcf78db8722
fix compile errors for SWT 3.4
Frank Benoit <benoit@tionex.de>
parents:
259
diff
changeset
|
131 * |
259 | 132 * @see IME#getText |
133 */ | |
240 | 134 public int getCommitCount () { |
135 checkWidget (); | |
136 return commitCount; | |
137 } | |
138 | |
259 | 139 /** |
140 * Returns the offset of the composition from the start of the document. | |
141 * This is the start offset of the composition within the document and | |
142 * in not changed by the input method editor itself during the in-line edit | |
143 * session. | |
144 * | |
145 * @return the offset of the composition | |
146 * | |
147 * @exception DWTException <ul> | |
148 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
149 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
150 * </ul> | |
151 */ | |
240 | 152 public int getCompositionOffset () { |
153 checkWidget (); | |
154 return startOffset; | |
155 } | |
156 | |
259 | 157 /** |
158 * Returns the ranges for the style that should be applied during the | |
159 * in-line edit session. | |
160 * <p> | |
161 * The ranges array contains start and end pairs. Each pair refers to | |
162 * the corresponding style in the styles array. For example, the pair | |
163 * that starts at ranges[n] and ends at ranges[n+1] uses the style | |
164 * at styles[n/2] returned by <code>getStyles()</code>. | |
165 * </p> | |
166 * @return the ranges for the styles | |
167 * | |
168 * @exception DWTException <ul> | |
169 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
170 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
171 * </ul> | |
261
edcf78db8722
fix compile errors for SWT 3.4
Frank Benoit <benoit@tionex.de>
parents:
259
diff
changeset
|
172 * |
259 | 173 * @see IME#getStyles |
174 */ | |
240 | 175 public int [] getRanges () { |
176 checkWidget (); | |
177 if (ranges is null) return new int [0]; | |
178 int [] result = new int [ranges.length]; | |
179 for (int i = 0; i < result.length; i++) { | |
180 result [i] = ranges [i] + startOffset; | |
181 } | |
182 return result; | |
183 } | |
184 | |
259 | 185 /** |
186 * Returns the styles for the ranges. | |
187 * <p> | |
188 * The ranges array contains start and end pairs. Each pair refers to | |
189 * the corresponding style in the styles array. For example, the pair | |
190 * that starts at ranges[n] and ends at ranges[n+1] uses the style | |
191 * at styles[n/2]. | |
192 * </p> | |
261
edcf78db8722
fix compile errors for SWT 3.4
Frank Benoit <benoit@tionex.de>
parents:
259
diff
changeset
|
193 * |
259 | 194 * @return the ranges for the styles |
195 * | |
196 * @exception DWTException <ul> | |
197 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
198 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
199 * </ul> | |
261
edcf78db8722
fix compile errors for SWT 3.4
Frank Benoit <benoit@tionex.de>
parents:
259
diff
changeset
|
200 * |
259 | 201 * @see IME#getRanges |
202 */ | |
240 | 203 public TextStyle [] getStyles () { |
204 checkWidget (); | |
205 if (styles is null) return new TextStyle [0]; | |
206 TextStyle [] result = new TextStyle [styles.length]; | |
207 System.arraycopy (styles, 0, result, 0, styles.length); | |
208 return result; | |
209 } | |
210 | |
259 | 211 /** |
212 * Returns the composition text. | |
213 * <p> | |
214 * The text for an IME is the characters in the widget that | |
215 * are in the current composition. When the commit count is | |
216 * equal to the length of the composition text, then the | |
217 * in-line edit operation is complete. | |
218 * </p> | |
219 * | |
220 * @return the widget text | |
221 * | |
222 * @exception DWTException <ul> | |
223 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
224 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
225 * </ul> | |
226 */ | |
240 | 227 public String getText () { |
228 checkWidget (); | |
229 return text; | |
230 } | |
231 | |
259 | 232 /** |
233 * Returns <code>true</code> if the caret should be wide, and | |
234 * <code>false</code> otherwise. In some languages, for example | |
235 * Korean, the caret is typically widened to the width of the | |
236 * current character in the in-line edit session. | |
261
edcf78db8722
fix compile errors for SWT 3.4
Frank Benoit <benoit@tionex.de>
parents:
259
diff
changeset
|
237 * |
259 | 238 * @return the wide caret state |
239 * | |
240 * @exception DWTException <ul> | |
241 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
242 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
243 * </ul> | |
244 */ | |
240 | 245 public bool getWideCaret () { |
246 checkWidget (); | |
247 return false; | |
248 } | |
249 | |
250 override int /*long*/ gtk_button_press_event (GtkWidget* widget, GdkEventButton* event) { | |
251 if (!isInlineEnabled ()) return 0; | |
252 auto imHandle_ = imHandle (); | |
253 if (imHandle_ !is null) OS.gtk_im_context_reset (imHandle_); | |
254 return 0; | |
255 } | |
256 | |
257 override int /*long*/ gtk_commit (GtkIMContext* imcontext, char* textPtr) { | |
258 if (!isInlineEnabled ()) return 0; | |
259 bool doit = true; | |
260 ranges = null; | |
261 styles = null; | |
262 caretOffset = commitCount = 0; | |
263 if (textPtr !is null && inComposition) { | |
264 int length = OS.strlen (textPtr); | |
265 if (length !is 0) { | |
255
5a30aa9820f3
removed tango.stdc.stringz imports and allow null for arrays and string arguments.
Frank Benoit <benoit@tionex.de>
parents:
240
diff
changeset
|
266 char [] chars = fromStringz(textPtr).dup; |
240 | 267 Event event = new Event(); |
268 event.detail = DWT.COMPOSITION_CHANGED; | |
269 event.start = startOffset; | |
270 event.end = startOffset + text.length; | |
271 event.text = text = chars !is null ? chars : ""; | |
272 commitCount = text.length; | |
273 sendEvent (DWT.ImeComposition, event); | |
274 doit = event.doit; | |
275 text = ""; | |
276 startOffset = -1; | |
277 commitCount = 0; | |
278 } | |
279 } | |
280 inComposition = false; | |
281 return doit ? 0 : 1; | |
282 } | |
283 | |
284 override int /*long*/ gtk_preedit_changed (GtkIMContext* imcontext) { | |
285 if (!isInlineEnabled ()) return 0; | |
286 ranges = null; | |
287 styles = null; | |
288 commitCount = 0; | |
289 auto imHandle_ = imHandle (); | |
290 char* preeditString; | |
291 void* pangoAttrs; | |
292 int cursorPos; | |
293 OS.gtk_im_context_get_preedit_string (imHandle_, &preeditString, &pangoAttrs, &cursorPos); | |
294 caretOffset = cursorPos ; | |
295 char [] chars = null; | |
296 if (preeditString !is null) { | |
297 int length = OS.strlen (preeditString); | |
255
5a30aa9820f3
removed tango.stdc.stringz imports and allow null for arrays and string arguments.
Frank Benoit <benoit@tionex.de>
parents:
240
diff
changeset
|
298 chars = fromStringz(preeditString).dup; |
240 | 299 if (pangoAttrs !is null) { |
300 int count = 0; | |
301 auto iterator = OS.pango_attr_list_get_iterator (pangoAttrs ); | |
302 while (OS.pango_attr_iterator_next (iterator)) count++; | |
303 OS.pango_attr_iterator_destroy (iterator); | |
304 ranges = new int [count * 2]; | |
305 styles = new TextStyle [count]; | |
306 iterator = OS.pango_attr_list_get_iterator (pangoAttrs ); | |
307 PangoAttrColor* attrColor; | |
308 PangoAttrInt* attrInt; | |
309 int start; | |
310 int end; | |
311 for (int i = 0; i < count; i++) { | |
312 OS.pango_attr_iterator_range (iterator, &start, &end); | |
313 ranges [i * 2] = cast(int)/*64*/OS.g_utf8_pointer_to_offset (preeditString, preeditString + start); | |
314 ranges [i * 2 + 1] = cast(int)/*64*/OS.g_utf8_pointer_to_offset (preeditString, preeditString + end) - 1; | |
315 styles [i] = new TextStyle (null, null, null); | |
316 auto attr = OS.pango_attr_iterator_get (iterator, OS.PANGO_ATTR_FOREGROUND); | |
317 if (attr !is null) { | |
318 attrColor = cast(PangoAttrColor*) attr; | |
319 GdkColor* color = new GdkColor (); | |
320 color.red = attrColor.color.red; | |
321 color.green = attrColor.color.green; | |
322 color.blue = attrColor.color.blue; | |
323 styles [i].foreground = Color.gtk_new (display, color); | |
324 } | |
325 attr = OS.pango_attr_iterator_get (iterator, OS.PANGO_ATTR_BACKGROUND); | |
326 if (attr !is null) { | |
327 attrColor = cast(PangoAttrColor*) attr; | |
328 GdkColor* color = new GdkColor (); | |
329 color.red = attrColor.color.red; | |
330 color.green = attrColor.color.green; | |
331 color.blue = attrColor.color.blue; | |
332 styles [i].background = Color.gtk_new (display, color); | |
333 } | |
334 attr = OS.pango_attr_iterator_get (iterator, OS.PANGO_ATTR_UNDERLINE); | |
335 if (attr !is null) { | |
336 attrInt = cast(PangoAttrInt*) attr; | |
337 styles [i].underline = attrInt.value !is OS.PANGO_UNDERLINE_NONE;; | |
338 styles [i].underlineStyle = DWT.UNDERLINE_SINGLE; | |
339 switch (attrInt.value) { | |
340 case OS.PANGO_UNDERLINE_DOUBLE: | |
341 styles [i].underlineStyle = DWT.UNDERLINE_DOUBLE; | |
342 break; | |
343 case OS.PANGO_UNDERLINE_ERROR: | |
344 styles [i].underlineStyle = DWT.UNDERLINE_ERROR; | |
345 break; | |
346 } | |
347 if (styles [i].underline) { | |
348 attr = OS.pango_attr_iterator_get(iterator, OS.PANGO_ATTR_UNDERLINE_COLOR); | |
349 if (attr !is null) { | |
350 attrColor = cast(PangoAttrColor*) attr; | |
351 GdkColor* color = new GdkColor; | |
352 color.red = attrColor.color.red; | |
353 color.green = attrColor.color.green; | |
354 color.blue = attrColor.color.blue; | |
355 styles [i].underlineColor = Color.gtk_new (display, color); | |
356 } | |
357 } | |
358 } | |
359 OS.pango_attr_iterator_next (iterator); | |
360 } | |
361 OS.pango_attr_iterator_destroy (iterator); | |
362 OS.pango_attr_list_unref (pangoAttrs); | |
363 } | |
364 OS.g_free (preeditString); | |
365 } | |
366 if (chars !is null) { | |
367 if (text.length is 0) startOffset = -1; | |
368 int end = startOffset + text.length; | |
369 if (startOffset is -1) { | |
370 Event event = new Event (); | |
371 event.detail = DWT.COMPOSITION_SELECTION; | |
372 sendEvent (DWT.ImeComposition, event); | |
373 startOffset = event.start; | |
374 end = event.end; | |
375 } | |
376 inComposition = true; | |
377 Event event = new Event (); | |
378 event.detail = DWT.COMPOSITION_CHANGED; | |
379 event.start = startOffset; | |
380 event.end = end; | |
381 event.text = text = chars !is null ? chars : ""; | |
382 sendEvent (DWT.ImeComposition, event); | |
383 } | |
384 return 1; | |
385 } | |
386 | |
387 GtkIMContext* imHandle () { | |
388 return parent.imHandle (); | |
389 } | |
390 | |
391 bool isInlineEnabled () { | |
392 return hooks (DWT.ImeComposition); | |
393 } | |
394 | |
395 void releaseParent () { | |
396 super.releaseParent (); | |
397 if (this is parent.getIME ()) parent.setIME (null); | |
398 } | |
399 | |
400 void releaseWidget () { | |
401 super.releaseWidget (); | |
402 parent = null; | |
403 text = null; | |
404 styles = null; | |
405 ranges = null; | |
406 } | |
407 | |
259 | 408 /** |
409 * Sets the offset of the composition from the start of the document. | |
410 * This is the start offset of the composition within the document and | |
411 * in not changed by the input method editor itself during the in-line edit | |
412 * session but may need to be changed by clients of the IME. For example, | |
413 * if during an in-line edit operation, a text editor inserts characters | |
414 * above the IME, then the IME must be informed that the composition | |
415 * offset has changed. | |
416 * | |
417 * @return the offset of the composition | |
418 * | |
419 * @exception DWTException <ul> | |
420 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
421 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
422 * </ul> | |
423 */ | |
240 | 424 public void setCompositionOffset (int offset) { |
425 checkWidget (); | |
426 if (offset < 0) return; | |
427 if (startOffset !is -1) { | |
428 startOffset = offset; | |
429 } | |
430 } | |
431 | |
432 } |