[gtk+/wip/matthiasc/emoji-picker: 7/11] wip: emoji picker
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/matthiasc/emoji-picker: 7/11] wip: emoji picker
- Date: Mon, 7 Aug 2017 13:02:43 +0000 (UTC)
commit 4f08860fefbc4f4ad4344abba022242e9e302ef3
Author: Matthias Clasen <mclasen redhat com>
Date: Sun Aug 6 07:39:30 2017 -0400
wip: emoji picker
tests/Makefile.am | 1 +
tests/gtkemojipicker.c | 456 +++++++++++++++++++++++++++++++++++++++++++++++
tests/gtkemojipicker.h | 13 ++
tests/gtkemojipicker.ui | 158 ++++++++++++++++
tests/testentryicons.c | 45 +++++
5 files changed, 673 insertions(+), 0 deletions(-)
---
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 40fafa9..fa667ba 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -310,6 +310,7 @@ testentrycompletion_SOURCES = \
testentrycompletion.c
testentryicons_SOURCES = \
+ gtkemojipicker.c \
testentryicons.c
testfilechooser_SOURCES = \
diff --git a/tests/gtkemojipicker.c b/tests/gtkemojipicker.c
new file mode 100644
index 0000000..b798e3c
--- /dev/null
+++ b/tests/gtkemojipicker.c
@@ -0,0 +1,456 @@
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include "gtkemojipicker.h"
+
+typedef struct {
+ gunichar code;
+ gboolean is_modifier_base;
+ gunichar code2;
+} EmojiData;
+
+static EmojiData people[] = {
+ // face-positive
+ { 0x1f600, 0, 0 },
+ { 0x1f601, 0, 0 },
+ { 0x1f602, 0, 0 },
+ { 0x1f923, 0, 0 },
+ { 0x1f603, 0, 0 },
+ { 0x1f604, 0, 0 },
+ { 0x1f605, 0, 0 },
+ { 0x1f606, 0, 0 },
+ { 0x1f609, 0, 0 },
+ { 0x1f60a, 0, 0 },
+ { 0x1f60b, 0, 0 },
+ { 0x1f60e, 0, 0 },
+ { 0x1f60d, 0, 0 },
+ { 0x1f618, 0, 0 },
+ { 0x1f617, 0, 0 },
+ { 0x1f619, 0, 0 },
+ { 0x1f61a, 0, 0 },
+ { 0x1f642, 0, 0 },
+ { 0x1f917, 0, 0 },
+ //{ 0x1f929, 0, 0 },
+ // face-neutral
+ { 0x1f914, 0, 0 },
+ //{ 0x1f928, 0 },
+ { 0x1f610, 0, 0 },
+ { 0x1f611, 0, 0 },
+ { 0x1f636, 0, 0 },
+ { 0x1f644, 0, 0 },
+ { 0x1f60f, 0, 0 },
+ { 0x1f623, 0, 0 },
+ { 0x1f625, 0, 0 },
+ { 0x1f62e, 0, 0 },
+ { 0x1f910, 0, 0 },
+ { 0x1f62f, 0, 0 },
+ { 0x1f62a, 0, 0 },
+ { 0x1f62b, 0, 0 },
+ { 0x1f634, 0, 0 },
+ { 0x1f60c, 0, 0 },
+ { 0x1f61b, 0, 0 },
+ { 0x1f61c, 0, 0 },
+ { 0x1f61d, 0, 0 },
+ { 0x1f924, 0, 0 },
+ { 0x1f612, 0, 0 },
+ { 0x1f613, 0, 0 },
+ { 0x1f614, 0, 0 },
+ { 0x1f615, 0, 0 },
+ { 0x1f643, 0, 0 },
+ { 0x1f911, 0, 0 },
+ { 0x1f632, 0, 0 },
+ //face-negative
+ { 0x02639, 0, 0 },
+ { 0x1f641, 0, 0 },
+ { 0x1f616, 0, 0 },
+ { 0x1f61e, 0, 0 },
+ { 0x1f61f, 0, 0 },
+ { 0x1f624, 0, 0 },
+ { 0x1f622, 0, 0 },
+ { 0x1f62d, 0, 0 },
+ { 0x1f626, 0, 0 },
+ { 0x1f627, 0, 0 },
+ { 0x1f628, 0, 0 },
+ { 0x1f629, 0, 0 },
+ //{ 0x1f92f, 0, 0 },
+ { 0x1f62c, 0, 0 },
+ { 0x1f630, 0, 0 },
+ { 0x1f631, 0, 0 },
+ { 0x1f633, 0, 0 },
+ //{ 0x1f92a, 0, 0 },
+ { 0x1f635, 0, 0 },
+ { 0x1f621, 0, 0 },
+ { 0x1f620, 0, 0 },
+ //{ 0x1f92c, 0, 0 },
+ // face-sick
+ { 0x1f637, 0, 0 },
+ { 0x1f912, 0, 0 },
+ { 0x1f915, 0, 0 },
+ { 0x1f922, 0, 0 },
+ //{ 0x1f92e, 0, 0 },
+ { 0x1f927, 0, 0 },
+ // face-role
+ { 0x1f607, 0, 0 },
+ { 0x1f920, 0, 0 },
+ { 0x1f921, 0, 0 },
+ { 0x1f925, 0, 0 },
+ //{ 0x1f92b, 0, 0 },
+ //{ 0x1f92d, 0, 0 },
+ //{ 0x1f9d0, 0, 0 },
+ { 0x1f913, 0, 0 },
+ // face-fantasy
+ { 0x1f608, 0, 0 },
+ { 0x1f47f, 0, 0 },
+ { 0x1f479, 0, 0 },
+ { 0x1f47a, 0, 0 },
+ { 0x1f480, 0, 0 },
+ { 0x02620, 0, 0 },
+ { 0x1f47b, 0, 0 },
+ { 0x1f47d, 0, 0 },
+ { 0x1f47e, 0, 0 },
+ { 0x1f916, 0, 0 },
+ { 0x1f4a9, 0, 0 },
+ // cat-face
+ { 0x1f63a, 0, 0 },
+ { 0x1f638, 0, 0 },
+ { 0x1f63b, 0, 0 },
+ { 0x1f63c, 0, 0 },
+ { 0x1f63d, 0, 0 },
+ { 0x1f640, 0, 0 },
+ { 0x1f63f, 0, 0 },
+ { 0x1f63e, 0, 0 },
+ // monkey-face
+ { 0x1f648, 0, 0 },
+ { 0x1f649, 0, 0 },
+ { 0x1f64a, 0, 0 },
+ // person
+ { 0x1f476, 1, 0 },
+ //{ 0x1f9d2, 1, 0 },
+ { 0x1f466, 1, 0 },
+ { 0x1f467, 1, 0 },
+ //{ 0x1f9d1, 1, 0 },
+ { 0x1f468, 1, 0 },
+ { 0x1f469, 1, 0 },
+ //{ 0x1f9d3, 1, 0 },
+ { 0x1f474, 1, 0 },
+ { 0x1f475, 1, 0 },
+ // person-role
+ //{ 0x1f468, 1, 0x02695 },
+ //{ 0x1f469, 1, 0x02695 },
+ //{ 0x1f468, 1, 0x1f393 },
+ //{ 0x1f469, 1, 0x1f393 },
+ //{ 0x1f468, 1, 0x1f3eb },
+ //{ 0x1f469, 1, 0x1f3eb },
+ //{ 0x1f468, 1, 0x02696 },
+ //{ 0x1f469, 1, 0x02696 },
+ //{ 0x1f468, 1, 0x1f33e },
+ //{ 0x1f469, 1, 0x1f33e },
+ //{ 0x1f468, 1, 0x1f373 },
+ //{ 0x1f469, 1, 0x1f373 },
+ //{ 0x1f468, 1, 0x1f527 },
+ //{ 0x1f469, 1, 0x1f527 },
+ //{ 0x1f468, 1, 0x1f3ed },
+ //{ 0x1f469, 1, 0x1f3ed },
+ //{ 0x1f468, 1, 0x1f4bc },
+ //{ 0x1f469, 1, 0x1f4bc },
+ //{ 0x1f468, 1, 0x1f52c },
+ //{ 0x1f469, 1, 0x1f52c },
+ //{ 0x1f468, 1, 0x1f4bb },
+ //{ 0x1f469, 1, 0x1f4bb },
+ //{ 0x1f468, 1, 0x1f3a4 },
+ //{ 0x1f469, 1, 0x1f3a4 },
+ //{ 0x1f468, 1, 0x1f3a8 },
+ //{ 0x1f469, 1, 0x1f3a8 },
+ //{ 0x1f468, 1, 0x02708 },
+ //{ 0x1f469, 1, 0x02708 },
+ //{ 0x1f468, 1, 0x1f680 },
+ //{ 0x1f469, 1, 0x1f680 },
+ //{ 0x1f468, 1, 0x1f692 },
+ //{ 0x1f469, 1, 0x1f692 },
+ { 0x1f46e, 1, 0 },
+ //{ 0x1f46e, 1, 0x2642 },
+ //{ 0x1f46e, 1, 0x2640 },
+ { 0x1f575, 1, 0 },
+ //{ 0x1f575, 1, 0x2642 },
+ //{ 0x1f575, 1, 0x2640 },
+ { 0x1f482, 1, 0 },
+ //{ 0x1f482, 1, 0x2642 },
+ //{ 0x1f482, 1, 0x2640 },
+ { 0x1f477, 1, 0 },
+ //{ 0x1f477, 1, 0x2642 },
+ //{ 0x1f477, 1, 0x2640 },
+ { 0x1f934, 1, 0 },
+ //{ 0x1f934, 1, 0x2642 },
+ //{ 0x1f934, 1, 0x2640 },
+ { 0x1f478, 1, 0 },
+ //{ 0x1f478, 1, 0x2642 },
+ //{ 0x1f478, 1, 0x2640 },
+ { 0x1f473, 1, 0 },
+ //{ 0x1f473, 1, 0x2642 },
+ //{ 0x1f473, 1, 0x2640 },
+ { 0x1f472, 1, 0 },
+ //{ 0x1f9d5, 1, 0 },
+ //{ 0x1f9d4, 1, 0 },
+ { 0x1f471, 1, 0 },
+ //{ 0x1f471, 1, 0x2642 },
+ //{ 0x1f471, 1, 0x2640 },
+ { 0x1f935, 1, 0 },
+ { 0x1f470, 1, 0 },
+ { 0x1f930, 1, 0 },
+ //{ 0x1f931, 1, 0 },
+ // person-fantasy
+ { 0x1f47c, 1, 0 },
+ { 0x1f385, 1, 0 },
+ { 0x1f936, 1, 0 },
+ //{ 0x1f9d9, 1, 0 },
+ //{ 0x1f9d9, 1, 0x2642 },
+ //{ 0x1f9d9, 1, 0x2640 },
+ //...
+ // person-gesture
+ { 0x1f64d, 1, 0 },
+ //{ 0x1f64d, 1, 0x2642 },
+ //{ 0x1f64d, 1, 0x2640 },
+ { 0x1f64e, 1, 0 },
+ //{ 0x1f64e, 1, 0x2642 },
+ //{ 0x1f64e, 1, 0x2640 },
+ { 0x1f645, 1, 0 },
+ //{ 0x1f645, 1, 0x2642 },
+ //{ 0x1f645, 1, 0x2640 },
+ { 0x1f646, 1, 0 },
+ //{ 0x1f646, 1, 0x2642 },
+ //{ 0x1f646, 1, 0x2640 },
+ { 0x1f481, 1, 0 },
+ //{ 0x1f481, 1, 0x2642 },
+ //{ 0x1f481, 1, 0x2640 },
+ { 0x1f64b, 1, 0 },
+ //{ 0x1f64b, 1, 0x2642 },
+ //{ 0x1f64b, 1, 0x2640 },
+ { 0x1f647, 1, 0 },
+ //{ 0x1f647, 1, 0x2642 },
+ //{ 0x1f647, 1, 0x2640 },
+ { 0x1f926, 1, 0 },
+ //{ 0x1f926, 1, 0x2642 },
+ //{ 0x1f926, 1, 0x2640 },
+ { 0x1f937, 1, 0 },
+ //{ 0x1f937, 1, 0x2642 },
+ //{ 0x1f937, 1, 0x2640 },
+ // person-activity
+ { 0x1f486, 1, 0 },
+ //{ 0x1f486, 1, 0x2642 },
+ //{ 0x1f486, 1, 0x2640 },
+ { 0x1f487, 1, 0 },
+ //{ 0x1f487, 1, 0x2642 },
+ //{ 0x1f487, 1, 0x2640 },
+ { 0x1f6b6, 1, 0 },
+ //{ 0x1f6b6, 1, 0x2642 },
+ //{ 0x1f6b6, 1, 0x2640 },
+ { 0x1f3c3, 1, 0 },
+ //{ 0x1f3c3, 1, 0x2642 },
+ //{ 0x1f3c3, 1, 0x2640 },
+ { 0x1f483, 1, 0 },
+ { 0x1f57a, 1, 0 },
+ { 0x1f46f, 1, 0 },
+ //{ 0x1f46f, 1, 0x2642 },
+ //{ 0x1f46f, 1, 0x2640 },
+ //...
+ // person-sport
+ // family
+ // body
+ // emotion
+ // clothing
+};
+
+
+struct _GtkEmojiPicker
+{
+ GtkPopover parent_instance;
+
+ GtkWidget *people_box;
+ GtkWidget *nature_box;
+
+ GtkGesture *people_press;
+};
+
+enum {
+ ACTIVATED,
+ LAST_SIGNAL
+};
+
+static int signals[LAST_SIGNAL];
+
+G_DEFINE_TYPE (GtkEmojiPicker, gtk_emoji_picker, GTK_TYPE_POPOVER)
+
+static void
+gtk_emoji_picker_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (gtk_emoji_picker_parent_class)->finalize (object);
+}
+
+static void
+emoji_activated (GtkFlowBox *box,
+ GtkFlowBoxChild *child,
+ gpointer data)
+{
+ const char *text;
+ GtkWidget *label;
+
+ gtk_popover_popdown (GTK_POPOVER (data));
+
+ label = gtk_bin_get_child (GTK_BIN (child));
+ text = gtk_label_get_label (GTK_LABEL (label));
+ g_signal_emit (data, signals[ACTIVATED], 0, text);
+}
+
+static void
+add_emoji (GtkWidget *box,
+ gunichar code,
+ gunichar modifier,
+ gboolean is_modifier_base,
+ gunichar code2);
+
+static void
+people_pressed_cb (GtkGesture *gesture,
+ double x,
+ double y,
+ gpointer data)
+{
+ GtkEmojiPicker *picker = data;
+ GtkWidget *child;
+ GtkWidget *popover;
+ GtkWidget *view;
+ GtkWidget *box;
+ gunichar code;
+ gunichar modifier;
+ gunichar code2;
+ gboolean is_modifier_base;
+ GtkWidget *parent_popover;
+
+ child = GTK_WIDGET (gtk_flow_box_get_child_at_pos (GTK_FLOW_BOX (picker->people_box), x, y));
+ if (!child)
+ return;
+
+ code = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (child), "code"));
+ code2 = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (child), "code2"));
+ is_modifier_base = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (child), "is-modifier-base"));
+ if (!is_modifier_base)
+ return;
+
+ parent_popover = gtk_widget_get_ancestor (child, GTK_TYPE_POPOVER);
+ popover = gtk_popover_new (child);
+ view = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_style_context_add_class (gtk_widget_get_style_context (view), "view");
+ box = gtk_flow_box_new ();
+ gtk_flow_box_set_homogeneous (GTK_FLOW_BOX (box), TRUE);
+ gtk_flow_box_set_min_children_per_line (GTK_FLOW_BOX (box), 6);
+ gtk_flow_box_set_max_children_per_line (GTK_FLOW_BOX (box), 6);
+ gtk_flow_box_set_activate_on_single_click (GTK_FLOW_BOX (box), TRUE);
+ gtk_flow_box_set_selection_mode (GTK_FLOW_BOX (box), GTK_SELECTION_NONE);
+ gtk_container_add (GTK_CONTAINER (popover), view);
+ gtk_container_add (GTK_CONTAINER (view), box);
+
+ g_signal_connect (box, "child-activated", G_CALLBACK (emoji_activated), parent_popover);
+
+ add_emoji (box, code, 0, FALSE, code2);
+ for (modifier = 0x1f3fb; modifier <= 0x1f3ff; modifier++) {
+ add_emoji (box, code, modifier, FALSE, code2);
+ }
+
+ gtk_popover_popup (GTK_POPOVER (popover));
+}
+
+static void
+add_emoji (GtkWidget *box,
+ gunichar code,
+ gunichar modifier,
+ gboolean is_modifier_base,
+ gunichar code2)
+{
+ GtkWidget *child;
+ GtkWidget *label;
+ PangoAttrList *attrs;
+ char text[32];
+ char *p = text;
+
+ p += g_unichar_to_utf8 (code, p);
+ if (modifier != 0)
+ p += g_unichar_to_utf8 (modifier, p);
+ if (code2 != 0) {
+ p += g_unichar_to_utf8 (0x200d, p);
+ p += g_unichar_to_utf8 (code2, p);
+ p += g_unichar_to_utf8 (0xfe0f, p);
+ }
+ p[0] = 0;
+
+ label = gtk_label_new (text);
+ g_object_set(label, "margin", 6, NULL);
+ attrs = pango_attr_list_new ();
+ pango_attr_list_insert (attrs, pango_attr_scale_new (PANGO_SCALE_X_LARGE));
+ gtk_label_set_attributes (GTK_LABEL (label), attrs);
+ pango_attr_list_unref (attrs);
+
+ child = gtk_flow_box_child_new ();
+ gtk_style_context_add_class (gtk_widget_get_style_context (child), "emojicell");
+ g_object_set_data (G_OBJECT (child), "code", GUINT_TO_POINTER (code));
+ g_object_set_data (G_OBJECT (child), "code2", GUINT_TO_POINTER (code2));
+ g_object_set_data (G_OBJECT (child), "is-modifier-base", GINT_TO_POINTER (is_modifier_base));
+
+ gtk_container_add (GTK_CONTAINER (child), label);
+ gtk_container_add (GTK_CONTAINER (box), child);
+}
+
+static void
+populate_emoji_picker (GtkEmojiPicker *picker)
+{
+ int i;
+
+ for (i = 0; i < G_N_ELEMENTS (people); i++) {
+ add_emoji (picker->people_box, people[i].code, 0, people[i].is_modifier_base,
people[i].code2);
+ }
+}
+
+static void
+gtk_emoji_picker_init (GtkEmojiPicker *picker)
+{
+ gtk_widget_init_template (GTK_WIDGET (picker));
+
+ picker->people_press = gtk_gesture_long_press_new (picker->people_box);
+ g_signal_connect (picker->people_press, "pressed", G_CALLBACK (people_pressed_cb), picker);
+
+ populate_emoji_picker (picker);
+}
+
+static void
+gtk_emoji_picker_class_init (GtkEmojiPickerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ GMappedFile *mf;
+ GBytes *bytes;
+
+ object_class->finalize = gtk_emoji_picker_finalize;
+
+ signals[ACTIVATED] = g_signal_new ("activated",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 1, G_TYPE_STRING|G_SIGNAL_TYPE_STATIC_SCOPE);
+
+ mf = g_mapped_file_new ("gtkemojipicker.ui", FALSE, NULL);
+ bytes = g_mapped_file_get_bytes (mf);
+ gtk_widget_class_set_template (widget_class, bytes);
+ g_bytes_unref (bytes);
+ g_mapped_file_unref (mf);
+
+ gtk_widget_class_bind_template_child (widget_class, GtkEmojiPicker, people_box);
+ gtk_widget_class_bind_template_child (widget_class, GtkEmojiPicker, nature_box);
+
+ gtk_widget_class_bind_template_callback (widget_class, emoji_activated);
+}
+
+GtkWidget *
+gtk_emoji_picker_new (void)
+{
+ return GTK_WIDGET (g_object_new (GTK_EMOJI_PICKER_TYPE, NULL));
+}
diff --git a/tests/gtkemojipicker.h b/tests/gtkemojipicker.h
new file mode 100644
index 0000000..8ef6e4a
--- /dev/null
+++ b/tests/gtkemojipicker.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GTK_EMOJI_PICKER_TYPE (gtk_emoji_picker_get_type ())
+
+G_DECLARE_FINAL_TYPE (GtkEmojiPicker, gtk_emoji_picker, GTK, EMOJI_PICKER, GtkPopover)
+
+GtkWidget *gtk_emoji_picker_new (void);
+
+G_END_DECLS
diff --git a/tests/gtkemojipicker.ui b/tests/gtkemojipicker.ui
new file mode 100644
index 0000000..6a35ed8
--- /dev/null
+++ b/tests/gtkemojipicker.ui
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface domain="gtk-3">
+ <template class="GtkEmojiPicker" parent="GtkPopover">
+ <property name="vexpand">1</property>
+ <property name="modal">1</property>
+ <child>
+ <object class="GtkBox" id="box">
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkSearchEntry" id="search_entry">
+ <property name="visible">0</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="swin">
+ <property name="vexpand">1</property>
+ <property name="hscrollbar-policy">never</property>
+ <property name="vscrollbar-policy">automatic</property>
+ <style>
+ <class name="view"/>
+ </style>
+ <child>
+ <object class="GtkBox" id="emoji_box">
+ <property name="orientation">vertical</property>
+ <property name="margin">6</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="yes">People</property>
+ <property name="xalign">0</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkFlowBox" id="people_box">
+ <property name="homogeneous">1</property>
+ <property name="selection-mode">none</property>
+ <property name="min-children-per-line">6</property>
+ <property name="max-children-per-line">6</property>
+ <property name="activate-on-single-click">1</property>
+ <signal name="child-activated" handler="emoji_activated"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="yes">Nature</property>
+ <property name="xalign">0</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkFlowBox" id="nature_box">
+ <property name="homogeneous">1</property>
+ <property name="selection-mode">none</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">6</property>
+ <property name="min-children-per-line">6</property>
+ <property name="max-children-per-line">6</property>
+ <property name="activate-on-single-click">1</property>
+ <signal name="child-activated" handler="emoji_activated"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="yes">Food</property>
+ <property name="xalign">0</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkFlowBox" id="food_box">
+ <property name="homogeneous">1</property>
+ <property name="selection-mode">none</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">6</property>
+ <property name="min-children-per-line">6</property>
+ <property name="max-children-per-line">6</property>
+ <property name="activate-on-single-click">1</property>
+ <signal name="child-activated" handler="emoji_activated"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="yes">Travel</property>
+ <property name="xalign">0</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkFlowBox" id="travel_box">
+ <property name="homogeneous">1</property>
+ <property name="selection-mode">none</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">6</property>
+ <property name="min-children-per-line">6</property>
+ <property name="max-children-per-line">6</property>
+ <property name="activate-on-single-click">1</property>
+ <signal name="child-activated" handler="emoji_activated"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="yes">Activities</property>
+ <property name="xalign">0</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkFlowBox" id="activities_box">
+ <property name="homogeneous">1</property>
+ <property name="selection-mode">none</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">6</property>
+ <property name="min-children-per-line">6</property>
+ <property name="max-children-per-line">6</property>
+ <property name="activate-on-single-click">1</property>
+ <signal name="child-activated" handler="emoji_activated"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="yes">Objects</property>
+ <property name="xalign">0</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkFlowBox" id="objects_box">
+ <property name="homogeneous">1</property>
+ <property name="selection-mode">none</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">6</property>
+ <property name="min-children-per-line">6</property>
+ <property name="max-children-per-line">6</property>
+ <property name="activate-on-single-click">1</property>
+ <signal name="child-activated" handler="emoji_activated"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="yes">Symbols</property>
+ <property name="xalign">0</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkFlowBox" id="symbols_box">
+ <property name="homogeneous">1</property>
+ <property name="selection-mode">none</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">6</property>
+ <property name="min-children-per-line">6</property>
+ <property name="max-children-per-line">6</property>
+ <property name="activate-on-single-click">1</property>
+ <signal name="child-activated" handler="emoji_activated"/>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/tests/testentryicons.c b/tests/testentryicons.c
index 41196a2..40eb0fc 100644
--- a/tests/testentryicons.c
+++ b/tests/testentryicons.c
@@ -1,5 +1,28 @@
#include <gtk/gtk.h>
#include <stdio.h>
+#include "gtkemojipicker.h"
+
+static void
+emoji_activated (GtkEmojiPicker *picker, const char *text, GtkEntry *entry)
+{
+ GtkEntryBuffer *buffer;
+ buffer = gtk_entry_get_buffer (entry);
+ gtk_entry_buffer_insert_text (buffer, -1, text, -1);
+}
+
+static void
+pick_emoji (GtkEntry *entry, gint icon, GdkEvent *event, gpointer data)
+{
+ GtkWidget *picker = gtk_emoji_picker_new ();
+ GdkRectangle rect;
+
+ gtk_popover_set_relative_to (GTK_POPOVER (picker), GTK_WIDGET (entry));
+ gtk_entry_get_icon_area (entry, GTK_ENTRY_ICON_SECONDARY, &rect);
+ gtk_popover_set_pointing_to (GTK_POPOVER (picker), &rect);
+ g_signal_connect (picker, "activated", G_CALLBACK (emoji_activated), entry);
+
+ gtk_popover_popup (GTK_POPOVER (picker));
+}
static void
clear_pressed (GtkEntry *entry, gint icon, GdkEvent *event, gpointer data)
@@ -270,8 +293,30 @@ main (int argc, char **argv)
g_signal_connect (button4, "toggled", G_CALLBACK (set_pixbuf), entry);
gtk_container_add (GTK_CONTAINER (box), button4);
+ label = gtk_label_new ("Emoji:");
+ gtk_grid_attach (GTK_GRID (grid), label, 0, 6, 1, 1);
+ gtk_widget_set_halign (label, GTK_ALIGN_START);
+ gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
+
+ entry = gtk_entry_new ();
+ gtk_widget_set_hexpand (entry, TRUE);
+ gtk_grid_attach (GTK_GRID (grid), entry, 1, 6, 1, 1);
gtk_widget_show (window);
+ gtk_entry_set_icon_from_icon_name (GTK_ENTRY (entry),
+ GTK_ENTRY_ICON_SECONDARY,
+ "face-smile-symbolic");
+
+ gtk_entry_set_icon_sensitive (GTK_ENTRY (entry),
+ GTK_ENTRY_ICON_SECONDARY,
+ TRUE);
+
+ gtk_entry_set_icon_activatable (GTK_ENTRY (entry),
+ GTK_ENTRY_ICON_SECONDARY,
+ TRUE);
+
+ g_signal_connect (entry, "icon-press", G_CALLBACK (pick_emoji), NULL);
+
gtk_main();
return 0;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]