Mercurial > projects > dwt-linux
diff dwt/widgets/IME.d @ 240:ce446666f5a2
Update to SWT 3.4M7
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Mon, 12 May 2008 19:13:01 +0200 |
parents | |
children | 5a30aa9820f3 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwt/widgets/IME.d Mon May 12 19:13:01 2008 +0200 @@ -0,0 +1,269 @@ +/******************************************************************************* + * Copyright (c) 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +module dwt.widgets.IME; + + +import dwt.DWT; +import dwt.graphics.Color; +import dwt.graphics.TextStyle; +import dwt.internal.Converter; +import dwt.internal.gtk.OS; + +import dwt.widgets.Widget; +import dwt.widgets.Canvas; +import dwt.widgets.Event; + +import dwt.dwthelper.utils; + +public class IME : Widget { + Canvas parent; + int caretOffset; + int startOffset; + int commitCount; + String text; + int [] ranges; + TextStyle [] styles; + bool inComposition; + +/** + * Prevents uninitialized instances from being created outside the package. + */ +this () { +} + +/** + * + * @see DWT + */ +public this (Canvas parent, int style) { + super (parent, style); + this.parent = parent; + createWidget (); +} + +void createWidget () { + text = ""; + startOffset = -1; + if (parent.getIME () is null) { + parent.setIME (this); + } +} + +public int getCaretOffset () { + checkWidget (); + return startOffset + caretOffset; +} + +public int getCommitCount () { + checkWidget (); + return commitCount; +} + +public int getCompositionOffset () { + checkWidget (); + return startOffset; +} + +public int [] getRanges () { + checkWidget (); + if (ranges is null) return new int [0]; + int [] result = new int [ranges.length]; + for (int i = 0; i < result.length; i++) { + result [i] = ranges [i] + startOffset; + } + return result; +} + +public TextStyle [] getStyles () { + checkWidget (); + if (styles is null) return new TextStyle [0]; + TextStyle [] result = new TextStyle [styles.length]; + System.arraycopy (styles, 0, result, 0, styles.length); + return result; +} + +public String getText () { + checkWidget (); + return text; +} + +public bool getWideCaret () { + checkWidget (); + return false; +} + +override int /*long*/ gtk_button_press_event (GtkWidget* widget, GdkEventButton* event) { + if (!isInlineEnabled ()) return 0; + auto imHandle_ = imHandle (); + if (imHandle_ !is null) OS.gtk_im_context_reset (imHandle_); + return 0; +} + +override int /*long*/ gtk_commit (GtkIMContext* imcontext, char* textPtr) { + if (!isInlineEnabled ()) return 0; + bool doit = true; + ranges = null; + styles = null; + caretOffset = commitCount = 0; + if (textPtr !is null && inComposition) { + int length = OS.strlen (textPtr); + if (length !is 0) { + char [] chars = tango.stdc.stringz.fromStringz(textPtr).dup; + Event event = new Event(); + event.detail = DWT.COMPOSITION_CHANGED; + event.start = startOffset; + event.end = startOffset + text.length; + event.text = text = chars !is null ? chars : ""; + commitCount = text.length; + sendEvent (DWT.ImeComposition, event); + doit = event.doit; + text = ""; + startOffset = -1; + commitCount = 0; + } + } + inComposition = false; + return doit ? 0 : 1; +} + +override int /*long*/ gtk_preedit_changed (GtkIMContext* imcontext) { + if (!isInlineEnabled ()) return 0; + ranges = null; + styles = null; + commitCount = 0; + auto imHandle_ = imHandle (); + char* preeditString; + void* pangoAttrs; + int cursorPos; + OS.gtk_im_context_get_preedit_string (imHandle_, &preeditString, &pangoAttrs, &cursorPos); + caretOffset = cursorPos ; + char [] chars = null; + if (preeditString !is null) { + int length = OS.strlen (preeditString); + chars = tango.stdc.stringz.fromStringz(preeditString).dup; + if (pangoAttrs !is null) { + int count = 0; + auto iterator = OS.pango_attr_list_get_iterator (pangoAttrs ); + while (OS.pango_attr_iterator_next (iterator)) count++; + OS.pango_attr_iterator_destroy (iterator); + ranges = new int [count * 2]; + styles = new TextStyle [count]; + iterator = OS.pango_attr_list_get_iterator (pangoAttrs ); + PangoAttrColor* attrColor; + PangoAttrInt* attrInt; + int start; + int end; + for (int i = 0; i < count; i++) { + OS.pango_attr_iterator_range (iterator, &start, &end); + ranges [i * 2] = cast(int)/*64*/OS.g_utf8_pointer_to_offset (preeditString, preeditString + start); + ranges [i * 2 + 1] = cast(int)/*64*/OS.g_utf8_pointer_to_offset (preeditString, preeditString + end) - 1; + styles [i] = new TextStyle (null, null, null); + auto attr = OS.pango_attr_iterator_get (iterator, OS.PANGO_ATTR_FOREGROUND); + if (attr !is null) { + attrColor = cast(PangoAttrColor*) attr; + GdkColor* color = new GdkColor (); + color.red = attrColor.color.red; + color.green = attrColor.color.green; + color.blue = attrColor.color.blue; + styles [i].foreground = Color.gtk_new (display, color); + } + attr = OS.pango_attr_iterator_get (iterator, OS.PANGO_ATTR_BACKGROUND); + if (attr !is null) { + attrColor = cast(PangoAttrColor*) attr; + GdkColor* color = new GdkColor (); + color.red = attrColor.color.red; + color.green = attrColor.color.green; + color.blue = attrColor.color.blue; + styles [i].background = Color.gtk_new (display, color); + } + attr = OS.pango_attr_iterator_get (iterator, OS.PANGO_ATTR_UNDERLINE); + if (attr !is null) { + attrInt = cast(PangoAttrInt*) attr; + styles [i].underline = attrInt.value !is OS.PANGO_UNDERLINE_NONE;; + styles [i].underlineStyle = DWT.UNDERLINE_SINGLE; + switch (attrInt.value) { + case OS.PANGO_UNDERLINE_DOUBLE: + styles [i].underlineStyle = DWT.UNDERLINE_DOUBLE; + break; + case OS.PANGO_UNDERLINE_ERROR: + styles [i].underlineStyle = DWT.UNDERLINE_ERROR; + break; + } + if (styles [i].underline) { + attr = OS.pango_attr_iterator_get(iterator, OS.PANGO_ATTR_UNDERLINE_COLOR); + if (attr !is null) { + attrColor = cast(PangoAttrColor*) attr; + GdkColor* color = new GdkColor; + color.red = attrColor.color.red; + color.green = attrColor.color.green; + color.blue = attrColor.color.blue; + styles [i].underlineColor = Color.gtk_new (display, color); + } + } + } + OS.pango_attr_iterator_next (iterator); + } + OS.pango_attr_iterator_destroy (iterator); + OS.pango_attr_list_unref (pangoAttrs); + } + OS.g_free (preeditString); + } + if (chars !is null) { + if (text.length is 0) startOffset = -1; + int end = startOffset + text.length; + if (startOffset is -1) { + Event event = new Event (); + event.detail = DWT.COMPOSITION_SELECTION; + sendEvent (DWT.ImeComposition, event); + startOffset = event.start; + end = event.end; + } + inComposition = true; + Event event = new Event (); + event.detail = DWT.COMPOSITION_CHANGED; + event.start = startOffset; + event.end = end; + event.text = text = chars !is null ? chars : ""; + sendEvent (DWT.ImeComposition, event); + } + return 1; +} + +GtkIMContext* imHandle () { + return parent.imHandle (); +} + +bool isInlineEnabled () { + return hooks (DWT.ImeComposition); +} + +void releaseParent () { + super.releaseParent (); + if (this is parent.getIME ()) parent.setIME (null); +} + +void releaseWidget () { + super.releaseWidget (); + parent = null; + text = null; + styles = null; + ranges = null; +} + +public void setCompositionOffset (int offset) { + checkWidget (); + if (offset < 0) return; + if (startOffset !is -1) { + startOffset = offset; + } +} + +}