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;
+    }
+}
+
+}