diff options
author | Matthias Clasen <mclasen@redhat.com> | 2021-08-17 21:55:33 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2021-08-17 22:33:26 -0400 |
commit | a06858ccd9804732e09f96dd8e6d5fc252ddf85e (patch) | |
tree | 56c94e5034188646146145d9cefa3eaf1191e59b /tests | |
parent | c6c48d327cd5219d591b0d566cde81108a162203 (diff) | |
download | gtk+-a06858ccd9804732e09f96dd8e6d5fc252ddf85e.tar.gz |
Add a custom input test
This shows the minimal work required to hook up an
im context to a custom widget.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/input.c | 153 | ||||
-rw-r--r-- | tests/meson.build | 1 |
2 files changed, 154 insertions, 0 deletions
diff --git a/tests/input.c b/tests/input.c new file mode 100644 index 0000000000..01099d2129 --- /dev/null +++ b/tests/input.c @@ -0,0 +1,153 @@ +/* Demonstrates hooking up an input method context to a custom widget. + */ +#include <gtk/gtk.h> + +G_DECLARE_FINAL_TYPE (DemoWidget, demo_widget, DEMO, WIDGET, GtkWidget) + +struct _DemoWidget +{ + GtkWidget parent_instance; + + GtkIMContext *im_context; + PangoLayout *layout; +}; + +struct _DemoWidgetClass +{ + GtkWidgetClass parent_class; +}; + +G_DEFINE_TYPE (DemoWidget, demo_widget, GTK_TYPE_WIDGET) + +static void +commit_cb (GtkIMContext *context, + const char *str, + DemoWidget *demo) +{ + pango_layout_set_text (demo->layout, str, -1); + pango_layout_set_attributes (demo->layout, NULL); + gtk_widget_queue_draw (GTK_WIDGET (demo)); +} + +static void +preedit_changed_cb (GtkIMContext *context, + DemoWidget *demo) +{ + char *str; + PangoAttrList *attrs; + int cursor_pos; + + gtk_im_context_get_preedit_string (context, &str, &attrs, &cursor_pos); + pango_layout_set_text (demo->layout, str, -1); + pango_layout_set_attributes (demo->layout, attrs); + g_free (str); + pango_attr_list_unref (attrs); + + gtk_widget_queue_draw (GTK_WIDGET (demo)); +} + +static gboolean +key_pressed_cb (GtkEventControllerKey *controller, + guint keyval, + guint keycode, + GdkModifierType state, + DemoWidget *demo) +{ + if (keyval == GDK_KEY_BackSpace) + { + pango_layout_set_text (demo->layout, "", -1); + pango_layout_set_attributes (demo->layout, NULL); + gtk_widget_queue_draw (GTK_WIDGET (demo)); + + return TRUE; + } + + return FALSE; +} + +static void +demo_widget_init (DemoWidget *demo) +{ + GtkEventController *controller; + + gtk_widget_set_focusable (GTK_WIDGET (demo), TRUE); + + demo->layout = gtk_widget_create_pango_layout (GTK_WIDGET (demo), ""); + + demo->im_context = gtk_im_multicontext_new (); + + g_signal_connect (demo->im_context, "commit", G_CALLBACK (commit_cb), demo); + g_signal_connect (demo->im_context, "preedit-changed", G_CALLBACK (preedit_changed_cb), demo); + + controller = gtk_event_controller_key_new (); + gtk_event_controller_key_set_im_context (GTK_EVENT_CONTROLLER_KEY (controller), + demo->im_context); + + g_signal_connect (controller, "key-pressed", G_CALLBACK (key_pressed_cb), demo); + + gtk_widget_add_controller (GTK_WIDGET (demo), controller); +} + +static void +demo_widget_dispose (GObject *object) +{ + DemoWidget *demo = DEMO_WIDGET (object); + + g_clear_object (&demo->layout); + g_clear_object (&demo->im_context); + + G_OBJECT_CLASS (demo_widget_parent_class)->dispose (object); +} + +static void +demo_widget_snapshot (GtkWidget *widget, + GtkSnapshot *snapshot) +{ + DemoWidget *demo = DEMO_WIDGET (widget); + + gtk_snapshot_render_layout (snapshot, + gtk_widget_get_style_context (widget), + 0, 0, + demo->layout); +} + +static void +demo_widget_class_init (DemoWidgetClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class); + + object_class->dispose = demo_widget_dispose; + + widget_class->snapshot = demo_widget_snapshot; +} + +static GtkWidget * +demo_widget_new (void) +{ + return g_object_new (demo_widget_get_type (), NULL); +} + +int +main (int argc, char *argv[]) +{ + GtkWindow *window; + GtkWidget *demo; + + gtk_init (); + + window = GTK_WINDOW (gtk_window_new ()); + + demo = demo_widget_new (); + + gtk_window_set_child (window, demo); + + gtk_window_present (window); + + gtk_widget_grab_focus (demo); + + while (g_list_model_get_n_items (gtk_window_get_toplevels ()) > 0) + g_main_context_iteration (NULL, TRUE); + + return 0; +} diff --git a/tests/meson.build b/tests/meson.build index b548db4e7a..9acf884231 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -1,5 +1,6 @@ gtk_tests = [ # testname, optional extra sources + ['input'], ['testpopup'], ['testupload'], ['testtransform'], |