diff options
author | Matthias Clasen <mclasen@redhat.com> | 2017-08-11 12:05:24 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2017-08-12 18:48:14 -0400 |
commit | 558aebfbc4699bf4182df16509fd8c19c0ffd6e3 (patch) | |
tree | 2a9fc72b7ee8aa65c9f9e5126a0571bdcdc76b71 /gtk/gtkentry.c | |
parent | 46f7804f3aac1e4007a93e6247d1587705e56e90 (diff) | |
download | gtk+-558aebfbc4699bf4182df16509fd8c19c0ffd6e3.tar.gz |
entry: Add support for an Emoji chooser
Add an "Insert Emoji" item to the context menu in entries.
We also add a show-emoji-icon property, which when set to
TRUE, will add an icon that can be clicked to bring up
the Emoji chooser.
Diffstat (limited to 'gtk/gtkentry.c')
-rw-r--r-- | gtk/gtkentry.c | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c index 7240ec9b0a..a0c2f5ca25 100644 --- a/gtk/gtkentry.c +++ b/gtk/gtkentry.c @@ -68,6 +68,7 @@ #include "gtkmagnifierprivate.h" #include "gtkcssnodeprivate.h" #include "gtkimageprivate.h" +#include "gtkemojichooser.h" #include "a11y/gtkentryaccessible.h" @@ -235,6 +236,7 @@ struct _GtkEntryPrivate gint64 handle_place_time; guint editable : 1; + guint show_emoji_icon : 1; guint in_drag : 1; guint overwrite_mode : 1; guint visible : 1; @@ -354,6 +356,7 @@ enum { PROP_ATTRIBUTES, PROP_POPULATE_ALL, PROP_TABS, + PROP_SHOW_EMOJI_ICON, PROP_EDITING_CANCELED, NUM_PROPERTIES = PROP_EDITING_CANCELED }; @@ -645,6 +648,8 @@ static void buffer_notify_max_length (GtkEntryBuffer *buffer, static void buffer_connect_signals (GtkEntry *entry); static void buffer_disconnect_signals (GtkEntry *entry); static GtkEntryBuffer *get_buffer (GtkEntry *entry); +static void set_show_emoji_icon (GtkEntry *entry, + gboolean value); static void gtk_entry_measure (GtkWidget *widget, GtkOrientation orientation, @@ -1375,6 +1380,21 @@ gtk_entry_class_init (GtkEntryClass *class) PANGO_TYPE_TAB_ARRAY, GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY); + /** + * GtkEntry::show-emoji-icon: + * + * When this is %TRUE, the entry will show an emoji icon in the secondary + * icon position that brings up the Emoji chooser when clicked. + * + * Since: 3.92 + */ + entry_props[PROP_SHOW_EMOJI_ICON] = + g_param_spec_boolean ("show-emoji-icon", + P_("Emoji icon"), + P_("Whether to show an icon for Emoji"), + FALSE, + GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY); + g_object_class_install_properties (gobject_class, NUM_PROPERTIES, entry_props); /** @@ -2130,6 +2150,10 @@ gtk_entry_set_property (GObject *object, gtk_entry_set_tabs (entry, g_value_get_boxed (value)); break; + case PROP_SHOW_EMOJI_ICON: + set_show_emoji_icon (entry, g_value_get_boolean (value)); + break; + case PROP_SCROLL_OFFSET: case PROP_CURSOR_POSITION: default: @@ -2358,6 +2382,10 @@ gtk_entry_get_property (GObject *object, g_value_set_boxed (value, priv->tabs); break; + case PROP_SHOW_EMOJI_ICON: + g_value_set_boolean (value, priv->show_emoji_icon); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -8406,6 +8434,8 @@ typedef struct GdkEvent *trigger_event; } PopupInfo; +static void gtk_entry_choose_emoji (GtkEntry *entry); + static void popup_targets_received (GtkClipboard *clipboard, GtkSelectionData *data, @@ -8462,6 +8492,15 @@ popup_targets_received (GtkClipboard *clipboard, gtk_widget_show (menuitem); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); + menuitem = gtk_menu_item_new_with_mnemonic (_("Insert _Emoji")); + gtk_widget_set_sensitive (menuitem, + mode == DISPLAY_NORMAL && + info_entry_priv->editable); + g_signal_connect_swapped (menuitem, "activate", + G_CALLBACK (gtk_entry_choose_emoji), entry); + gtk_widget_show (menuitem); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); + g_signal_emit (entry, signals[POPULATE_POPUP], 0, menu); if (info->trigger_event && gdk_event_triggers_context_menu (info->trigger_event)) @@ -9792,3 +9831,68 @@ gtk_entry_get_tabs (GtkEntry *entry) return entry->priv->tabs; } + +static void +gtk_entry_choose_emoji (GtkEntry *entry) +{ + GtkWidget *chooser; + GdkRectangle rect; + + chooser = GTK_WIDGET (g_object_get_data (G_OBJECT (entry), "gtk-emoji-chooser")); + if (!chooser) + { + chooser = gtk_emoji_chooser_new (); + g_object_set_data_full (G_OBJECT (entry), "gtk-emoji-chooser", chooser, (GDestroyNotify)gtk_widget_destroy); + + gtk_popover_set_relative_to (GTK_POPOVER (chooser), GTK_WIDGET (entry)); + if (entry->priv->show_emoji_icon) + { + gtk_entry_get_icon_area (entry, GTK_ENTRY_ICON_SECONDARY, &rect); + gtk_popover_set_pointing_to (GTK_POPOVER (chooser), &rect); + } + g_signal_connect_swapped (chooser, "emoji-picked", G_CALLBACK (gtk_entry_enter_text), entry); + } + + gtk_popover_popup (GTK_POPOVER (chooser)); +} + +static void +pick_emoji (GtkEntry *entry, + int icon, + GdkEvent *event, + gpointer data) +{ + gtk_entry_choose_emoji (entry); +} + +static void +set_show_emoji_icon (GtkEntry *entry, + gboolean value) +{ + GtkEntryPrivate *priv = entry->priv; + + if (priv->show_emoji_icon == value) + return; + + priv->show_emoji_icon = value; + + if (priv->show_emoji_icon) + { + 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); + } + + g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_SHOW_EMOJI_ICON]); + gtk_widget_queue_resize (GTK_WIDGET (entry)); +} |