aboutsummaryrefslogtreecommitdiffhomepage
path: root/gtk/ScintillaGTK.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'gtk/ScintillaGTK.cxx')
-rw-r--r--gtk/ScintillaGTK.cxx120
1 files changed, 110 insertions, 10 deletions
diff --git a/gtk/ScintillaGTK.cxx b/gtk/ScintillaGTK.cxx
index 8c2f5c6ea..f29c8b627 100644
--- a/gtk/ScintillaGTK.cxx
+++ b/gtk/ScintillaGTK.cxx
@@ -102,6 +102,8 @@ class ScintillaGTK : public ScintillaBase {
GdkIC *ic;
GdkICAttr *ic_attr;
#else
+ Window wPreedit;
+ Window wPreeditDraw;
GtkIMContext *im_context;
#endif
#endif
@@ -197,8 +199,12 @@ private:
static gint KeyPress(GtkWidget *widget, GdkEventKey *event);
static gint KeyRelease(GtkWidget *widget, GdkEventKey *event);
#if GTK_MAJOR_VERSION >= 2
+ static gint ExposePreedit(GtkWidget *widget, GdkEventExpose *ose, ScintillaGTK *sciThis);
+ gint ExposePreeditThis(GtkWidget *widget, GdkEventExpose *ose);
static void Commit(GtkIMContext *context, char *str, ScintillaGTK *sciThis);
void CommitThis(char *str);
+ static void PreeditChanged(GtkIMContext *context, ScintillaGTK *sciThis);
+ void PreeditChangedThis();
#endif
static void Destroy(GtkObject *object);
static void SelectionReceived(GtkWidget *widget, GtkSelectionData *selection_data,
@@ -388,9 +394,20 @@ void ScintillaGTK::RealizeThis(GtkWidget *widget) {
}
}
#else
+ wPreedit = gtk_window_new(GTK_WINDOW_POPUP);
+ wPreeditDraw = gtk_drawing_area_new();
+ gtk_signal_connect(GTK_OBJECT(PWidget(wPreeditDraw)), "expose_event",
+ GtkSignalFunc(ExposePreedit), this);
+ gtk_container_add(GTK_CONTAINER(PWidget(wPreedit)), PWidget(wPreeditDraw));
+ gtk_widget_realize(PWidget(wPreedit));
+ gtk_widget_realize(PWidget(wPreeditDraw));
+ gtk_widget_show(PWidget(wPreeditDraw));
+
im_context = gtk_im_multicontext_new();
g_signal_connect(im_context, "commit",
G_CALLBACK(Commit), this);
+ g_signal_connect(im_context, "preedit_changed",
+ G_CALLBACK(PreeditChanged), this);
gtk_im_context_set_client_window(im_context, widget->window);
#endif
#endif
@@ -423,6 +440,8 @@ void ScintillaGTK::UnRealizeThis(GtkWidget *widget) {
ic_attr = NULL;
}
#else
+ gtk_widget_unrealize(PWidget(wPreedit));
+ gtk_widget_unrealize(PWidget(wPreeditDraw));
g_object_unref(im_context);
#endif
#endif
@@ -495,10 +514,10 @@ void ScintillaGTK::MainForAll(GtkContainer *container, gboolean include_internal
#if GTK_MAJOR_VERSION < 2
gint ScintillaGTK::CursorMoved(GtkWidget *widget, int xoffset, int yoffset, ScintillaGTK *sciThis) {
if (GTK_WIDGET_HAS_FOCUS(widget) && gdk_im_ready() && sciThis->ic &&
- (gdk_ic_get_style (sciThis->ic) & GDK_IM_PREEDIT_POSITION)) {
+ (gdk_ic_get_style(sciThis->ic) & GDK_IM_PREEDIT_POSITION)) {
sciThis->ic_attr->spot_location.x = xoffset;
sciThis->ic_attr->spot_location.y = yoffset;
- gdk_ic_set_attr (sciThis->ic, sciThis->ic_attr, GDK_IC_SPOT_LOCATION);
+ gdk_ic_set_attr(sciThis->ic, sciThis->ic_attr, GDK_IC_SPOT_LOCATION);
}
return FALSE;
}
@@ -530,6 +549,15 @@ gint ScintillaGTK::FocusIn(GtkWidget *widget, GdkEventFocus * /*event*/) {
if (sciThis->ic)
gdk_im_begin(sciThis->ic, widget->window);
#else
+ gchar *str;
+ gint cursor_pos;
+ gtk_im_context_get_preedit_string(sciThis->im_context, &str, NULL, &cursor_pos);
+ if (strlen(str) > 0){
+ gtk_widget_show(PWidget(sciThis->wPreedit));
+ } else{
+ gtk_widget_hide(PWidget(sciThis->wPreedit));
+ }
+ g_free(str);
gtk_im_context_focus_in(sciThis->im_context);
#endif
#endif
@@ -547,6 +575,7 @@ gint ScintillaGTK::FocusOut(GtkWidget *widget, GdkEventFocus * /*event*/) {
#if GTK_MAJOR_VERSION < 2
gdk_im_end();
#else
+ gtk_widget_hide(PWidget(sciThis->wPreedit));
gtk_im_context_focus_out(sciThis->im_context);
#endif
#endif
@@ -577,7 +606,7 @@ void ScintillaGTK::SizeAllocate(GtkWidget *widget, GtkAllocation *allocation) {
#ifdef INTERNATIONAL_INPUT
#if GTK_MAJOR_VERSION < 2
- if (sciThis->ic && (gdk_ic_get_style (sciThis->ic) & GDK_IM_PREEDIT_POSITION)) {
+ if (sciThis->ic && (gdk_ic_get_style(sciThis->ic) & GDK_IM_PREEDIT_POSITION)) {
gint width, height;
gdk_window_get_size(widget->window, &width, &height);
@@ -1767,9 +1796,6 @@ static int KeyTranslate(int keyIn) {
gint ScintillaGTK::KeyThis(GdkEventKey *event) {
//Platform::DebugPrintf("SC-key: %d %x [%s]\n",
// event->keyval, event->state, (event->length > 0) ? event->string : "empty");
- if (!event->keyval) {
- return true;
- }
#if GTK_MAJOR_VERSION >= 2
if (UseInputMethod()) {
if (gtk_im_context_filter_keypress(im_context, event)) {
@@ -1777,6 +1803,9 @@ gint ScintillaGTK::KeyThis(GdkEventKey *event) {
}
}
#endif
+ if (!event->keyval) {
+ return true;
+ }
bool shift = (event->state & GDK_SHIFT_MASK) != 0;
bool ctrl = (event->state & GDK_CONTROL_MASK) != 0;
@@ -1822,6 +1851,40 @@ gint ScintillaGTK::KeyRelease(GtkWidget *, GdkEventKey * /*event*/) {
}
#if GTK_MAJOR_VERSION >= 2
+gint ScintillaGTK::ExposePreedit(GtkWidget *widget, GdkEventExpose *ose, ScintillaGTK *sciThis) {
+ return sciThis->ExposePreeditThis(widget, ose);
+}
+
+gint ScintillaGTK::ExposePreeditThis(GtkWidget *widget, GdkEventExpose *ose) {
+ gchar *str;
+ gint cursor_pos;
+ PangoAttrList *attrs;
+
+ gtk_im_context_get_preedit_string(im_context, &str, &attrs, &cursor_pos);
+ PangoLayout *layout = gtk_widget_create_pango_layout(PWidget(wText), str);
+ pango_layout_set_attributes(layout, attrs);
+
+ GdkGC *gc = gdk_gc_new(widget->window);
+ GdkColor color[2] = { {0, 0x0000, 0x0000, 0x0000},
+ {0, 0xffff, 0xffff, 0xffff}};
+ gdk_color_alloc(gdk_colormap_get_system(), color);
+ gdk_color_alloc(gdk_colormap_get_system(), color + 1);
+
+ gdk_gc_set_foreground(gc, color + 1);
+ gdk_draw_rectangle(widget->window, gc, TRUE, ose->area.x, ose->area.y,
+ ose->area.width, ose->area.height);
+
+ gdk_gc_set_foreground(gc, color);
+ gdk_gc_set_background(gc, color + 1);
+ gdk_draw_layout(widget->window, gc, 0, 0, layout);
+
+ gdk_gc_unref(gc);
+ g_free(str);
+ pango_attr_list_unref(attrs);
+ g_object_unref(layout);
+ return TRUE;
+}
+
void ScintillaGTK::Commit(GtkIMContext *, char *str, ScintillaGTK *sciThis) {
sciThis->CommitThis(str);
}
@@ -1829,6 +1892,43 @@ void ScintillaGTK::Commit(GtkIMContext *, char *str, ScintillaGTK *sciThis) {
void ScintillaGTK::CommitThis(char *str) {
AddCharUTF(str, strlen(str));
}
+
+void ScintillaGTK::PreeditChanged(GtkIMContext *, ScintillaGTK *sciThis) {
+ sciThis->PreeditChangedThis();
+}
+
+void ScintillaGTK::PreeditChangedThis() {
+ gchar *str;
+ PangoAttrList *attrs;
+ gint cursor_pos;
+ gtk_im_context_get_preedit_string(im_context, &str, &attrs, &cursor_pos);
+ if (strlen(str) > 0){
+ PangoLayout *layout = gtk_widget_create_pango_layout(PWidget(wText), str);
+ pango_layout_set_attributes(layout, attrs);
+
+ gint w, h;
+ pango_layout_get_pixel_size(layout, &w, &h);
+ g_object_unref(layout);
+
+ gint x, y;
+ gdk_window_get_origin((PWidget(wText))->window, &x, &y);
+
+ Point pt = LocationFromPosition(currentPos);
+ if (pt.x < 0)
+ pt.x = 0;
+ if (pt.y < 0)
+ pt.y = 0;
+
+ gtk_window_move(GTK_WINDOW(PWidget(wPreedit)), x+pt.x, y+pt.y);
+ gtk_window_resize(GTK_WINDOW(PWidget(wPreedit)), w, h);
+ gtk_widget_show(PWidget(wPreedit));
+ gtk_widget_queue_draw_area(PWidget(wPreeditDraw), 0, 0, w, h);
+ } else {
+ gtk_widget_hide(PWidget(wPreedit));
+ }
+ g_free(str);
+ pango_attr_list_unref(attrs);
+}
#endif
void ScintillaGTK::Destroy(GtkObject* object) {
@@ -1840,8 +1940,8 @@ void ScintillaGTK::Destroy(GtkObject* object) {
//Platform::DebugPrintf("Destroying %x %x\n", sciThis, object);
sciThis->Finalise();
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+ if (GTK_OBJECT_CLASS(parent_class)->destroy)
+ (* GTK_OBJECT_CLASS(parent_class)->destroy)(object);
delete sciThis;
scio->pscin = 0;
@@ -2130,8 +2230,8 @@ sptr_t scintilla_send_message(ScintillaObject *sci, unsigned int iMessage, uptr_
return psci->WndProc(iMessage, wParam, lParam);
}
-static void scintilla_class_init (ScintillaClass *klass);
-static void scintilla_init (ScintillaObject *sci);
+static void scintilla_class_init(ScintillaClass *klass);
+static void scintilla_init(ScintillaObject *sci);
extern void Platform_Initialise();
extern void Platform_Finalise();