[gtk+/wip/emoji/preview: 2/5] emoji: Add a preview to the chooser



commit 266212944821b8caffc369d4207fd871f8299f8c
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Aug 27 14:41:54 2017 -0400

    emoji: Add a preview to the chooser
    
    This lets us show just the current emoji in a bigger size,
    and also lets us show the name, so users can learn what
    to search for.

 gtk/gtkemojichooser.c          |   85 ++++++++++++++++----
 gtk/theme/Adwaita/_common.scss |   12 ++-
 gtk/ui/gtkemojichooser.ui      |  172 +++++++++++++++++++++++-----------------
 3 files changed, 177 insertions(+), 92 deletions(-)
---
diff --git a/gtk/gtkemojichooser.c b/gtk/gtkemojichooser.c
index 302f7d7..41f6449 100644
--- a/gtk/gtkemojichooser.c
+++ b/gtk/gtkemojichooser.c
@@ -61,6 +61,9 @@ struct _GtkEmojiChooser
   EmojiSection symbols;
   EmojiSection flags;
 
+  GtkWidget *emoji_preview;
+  GtkWidget *emoji_name_preview;
+
   GtkGesture *recent_press;
   GtkGesture *people_press;
   GtkGesture *body_press;
@@ -118,10 +121,11 @@ scroll_to_section (GtkButton *button,
 }
 
 static void
-add_emoji (GtkWidget    *box,
-           gboolean      prepend,
-           GVariant     *item,
-           gunichar      modifier);
+add_emoji (GtkEmojiChooser *chooser,
+           GtkWidget       *box,
+           gboolean         prepend,
+           GVariant        *item,
+           gunichar         modifier);
 
 #define MAX_RECENT (7*3)
 
@@ -141,7 +145,7 @@ populate_recent_section (GtkEmojiChooser *chooser)
 
       emoji_data = g_variant_get_child_value (item, 0);
       g_variant_get_child (item, 1, "u", &modifier);
-      add_emoji (chooser->recent.box, FALSE, emoji_data, modifier);
+      add_emoji (chooser, chooser->recent.box, FALSE, emoji_data, modifier);
       g_variant_unref (emoji_data);
       g_variant_unref (item);
     }
@@ -184,7 +188,7 @@ add_recent_item (GtkEmojiChooser *chooser,
     }
   g_list_free (children);
 
-  add_emoji (chooser->recent.box, TRUE, item, modifier);
+  add_emoji (chooser, chooser->recent.box, TRUE, item, modifier);
 
   g_settings_set_value (chooser->settings, "recent-emoji", g_variant_builder_end (&builder));
 
@@ -221,6 +225,7 @@ long_pressed_cb (GtkGesture *gesture,
                  double      y,
                  gpointer    data)
 {
+  GtkEmojiChooser *chooser = data;
   GtkWidget *child;
   GtkWidget *popover;
   GtkWidget *view;
@@ -272,24 +277,19 @@ long_pressed_cb (GtkGesture *gesture,
 
   g_signal_connect (box, "child-activated", G_CALLBACK (emoji_activated), parent_popover);
 
-  add_emoji (box, FALSE, emoji_data, 0);
+  add_emoji (chooser, box, FALSE, emoji_data, 0);
   for (modifier = 0x1f3fb; modifier <= 0x1f3ff; modifier++)
-    add_emoji (box, FALSE, emoji_data, modifier);
+    add_emoji (chooser, box, FALSE, emoji_data, modifier);
 
   gtk_popover_popup (GTK_POPOVER (popover));
 }
 
 static void
-add_emoji (GtkWidget    *box,
-           gboolean      prepend,
-           GVariant     *item,
-           gunichar      modifier)
+codes_to_utf8 (GVariant *item,
+               gunichar  modifier,
+               char      text[])
 {
-  GtkWidget *child;
-  GtkWidget *label;
-  PangoAttrList *attrs;
   GVariant *codes;
-  char text[64];
   char *p = text;
   int i;
 
@@ -305,7 +305,52 @@ add_emoji (GtkWidget    *box,
         p += g_unichar_to_utf8 (code, p);
     }
    p[0] = 0;
+}
+
+static gboolean
+enter_or_leave (GtkWidget        *child,
+                GdkEventCrossing *event,
+                gpointer          data)
+{
+  GtkEmojiChooser *chooser = data;
+
+  if (gdk_event_get_event_type ((GdkEvent *)event) == GDK_ENTER_NOTIFY)
+    {
+      GVariant *emoji_data;
+      gunichar modifier;
+      const char *name;
+      char text[64];
+
+      emoji_data = (GVariant*) g_object_get_data (G_OBJECT (child), "emoji-data");
+      modifier = (gunichar) GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (child), "modifier"));
+      g_variant_get_child (emoji_data, 1, "&s", &name);
 
+      codes_to_utf8 (emoji_data, modifier, text);
+      gtk_label_set_text (GTK_LABEL (chooser->emoji_preview), text);
+      gtk_label_set_text (GTK_LABEL (chooser->emoji_name_preview), name);
+    }
+  else
+    {
+      gtk_label_set_text (GTK_LABEL (chooser->emoji_preview), "");
+      gtk_label_set_text (GTK_LABEL (chooser->emoji_name_preview), "");
+    }
+
+  return GDK_EVENT_PROPAGATE;
+}
+
+static void
+add_emoji (GtkEmojiChooser *chooser,
+           GtkWidget       *box,
+           gboolean         prepend,
+           GVariant        *item,
+           gunichar         modifier)
+{
+  GtkWidget *child;
+  GtkWidget *label;
+  PangoAttrList *attrs;
+  char text[64];
+
+  codes_to_utf8 (item, modifier, text);
   label = gtk_label_new (text);
   attrs = pango_attr_list_new ();
   pango_attr_list_insert (attrs, pango_attr_scale_new (PANGO_SCALE_X_LARGE));
@@ -322,6 +367,9 @@ add_emoji (GtkWidget    *box,
 
   gtk_container_add (GTK_CONTAINER (child), label);
   gtk_flow_box_insert (GTK_FLOW_BOX (box), child, prepend ? 0 : -1);
+
+  g_signal_connect (child, "enter-notify-event", G_CALLBACK (enter_or_leave), chooser);
+  g_signal_connect (child, "leave-notify-event", G_CALLBACK (enter_or_leave), chooser);
 }
 
 static void
@@ -360,7 +408,7 @@ populate_emoji_chooser (GtkEmojiChooser *chooser)
       else if (strcmp (name, chooser->flags.first) == 0)
         box = chooser->flags.box;
 
-      add_emoji (box, FALSE, item, 0);
+      add_emoji (chooser, box, FALSE, item, 0);
     }
 
   g_bytes_unref (bytes);
@@ -620,6 +668,9 @@ gtk_emoji_chooser_class_init (GtkEmojiChooserClass *klass)
   gtk_widget_class_bind_template_child (widget_class, GtkEmojiChooser, flags.heading);
   gtk_widget_class_bind_template_child (widget_class, GtkEmojiChooser, flags.button);
 
+  gtk_widget_class_bind_template_child (widget_class, GtkEmojiChooser, emoji_preview);
+  gtk_widget_class_bind_template_child (widget_class, GtkEmojiChooser, emoji_name_preview);
+
   gtk_widget_class_bind_template_callback (widget_class, emoji_activated);
   gtk_widget_class_bind_template_callback (widget_class, search_changed);
 }
diff --git a/gtk/theme/Adwaita/_common.scss b/gtk/theme/Adwaita/_common.scss
index 8f7c006..5253a9c 100644
--- a/gtk/theme/Adwaita/_common.scss
+++ b/gtk/theme/Adwaita/_common.scss
@@ -4411,11 +4411,17 @@ button.emoji-section:backdrop { color: $backdrop_borders_color; }
 button.emoji-section:backdrop:checked { color: $backdrop_fg_color; }
 
 .emoji {
-  font-size: x-large;
-  padding: 6px;
-  border-radius: 6px;
+  font-size: small;
+  padding: 4px;
+  border-radius: 4px;
 }
 
 .emoji:hover {
   background: $selected_bg_color;
 }
+
+.preview .emoji:hover,
+.preview .emoji {
+  font-size: xx-large;
+  background: none;
+}
diff --git a/gtk/ui/gtkemojichooser.ui b/gtk/ui/gtkemojichooser.ui
index cbf851b..953e09a 100644
--- a/gtk/ui/gtkemojichooser.ui
+++ b/gtk/ui/gtkemojichooser.ui
@@ -19,6 +19,90 @@
               <object class="GtkBox">
                 <property name="orientation">vertical</property>
                 <child>
+                  <object class="GtkBox">
+                    <child>
+                      <object class="GtkButton" id="recent.button">
+                        <property name="relief">none</property>
+                        <style>
+                          <class name="emoji-section"/>
+                        </style>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="people.button">
+                        <property name="relief">none</property>
+                        <style>
+                          <class name="emoji-section"/>
+                        </style>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="body.button">
+                        <property name="relief">none</property>
+                        <style>
+                          <class name="emoji-section"/>
+                        </style>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="nature.button">
+                        <property name="relief">none</property>
+                        <style>
+                          <class name="emoji-section"/>
+                        </style>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="food.button">
+                        <property name="relief">none</property>
+                        <style>
+                          <class name="emoji-section"/>
+                        </style>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="travel.button">
+                        <property name="relief">none</property>
+                        <style>
+                          <class name="emoji-section"/>
+                        </style>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="activities.button">
+                        <property name="relief">none</property>
+                        <style>
+                          <class name="emoji-section"/>
+                        </style>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="objects.button">
+                        <property name="relief">none</property>
+                        <style>
+                          <class name="emoji-section"/>
+                        </style>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="symbols.button">
+                        <property name="relief">none</property>
+                        <style>
+                          <class name="emoji-section"/>
+                        </style>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="flags.button">
+                        <property name="relief">none</property>
+                        <style>
+                          <class name="emoji-section"/>
+                        </style>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+                <child>
                   <object class="GtkScrolledWindow" id="scrolled_window">
                     <property name="vexpand">1</property>
                     <property name="hscrollbar-policy">never</property>
@@ -35,6 +119,7 @@
                           <object class="GtkFlowBox" id="recent.box">
                             <property name="homogeneous">1</property>
                             <property name="selection-mode">none</property>
+                            <property name="max-children-per-line">10</property>
                             <signal name="child-activated" handler="emoji_activated"/>
                           </object>
                         </child>
@@ -48,6 +133,7 @@
                           <object class="GtkFlowBox" id="people.box">
                             <property name="homogeneous">1</property>
                             <property name="selection-mode">none</property>
+                            <property name="max-children-per-line">10</property>
                             <signal name="child-activated" handler="emoji_activated"/>
                           </object>
                         </child>
@@ -61,6 +147,7 @@
                           <object class="GtkFlowBox" id="body.box">
                             <property name="homogeneous">1</property>
                             <property name="selection-mode">none</property>
+                            <property name="max-children-per-line">10</property>
                             <signal name="child-activated" handler="emoji_activated"/>
                           </object>
                         </child>
@@ -74,6 +161,7 @@
                           <object class="GtkFlowBox" id="nature.box">
                             <property name="homogeneous">1</property>
                             <property name="selection-mode">none</property>
+                            <property name="max-children-per-line">10</property>
                             <signal name="child-activated" handler="emoji_activated"/>
                           </object>
                         </child>
@@ -87,6 +175,7 @@
                           <object class="GtkFlowBox" id="food.box">
                             <property name="homogeneous">1</property>
                             <property name="selection-mode">none</property>
+                            <property name="max-children-per-line">10</property>
                             <signal name="child-activated" handler="emoji_activated"/>
                           </object>
                         </child>
@@ -100,6 +189,7 @@
                           <object class="GtkFlowBox" id="travel.box">
                             <property name="homogeneous">1</property>
                             <property name="selection-mode">none</property>
+                            <property name="max-children-per-line">10</property>
                             <signal name="child-activated" handler="emoji_activated"/>
                           </object>
                         </child>
@@ -113,6 +203,7 @@
                           <object class="GtkFlowBox" id="activities.box">
                             <property name="homogeneous">1</property>
                             <property name="selection-mode">none</property>
+                            <property name="max-children-per-line">10</property>
                             <signal name="child-activated" handler="emoji_activated"/>
                           </object>
                         </child>
@@ -126,6 +217,7 @@
                           <object class="GtkFlowBox" id="objects.box">
                             <property name="homogeneous">1</property>
                             <property name="selection-mode">none</property>
+                            <property name="max-children-per-line">10</property>
                             <signal name="child-activated" handler="emoji_activated"/>
                           </object>
                         </child>
@@ -139,6 +231,7 @@
                           <object class="GtkFlowBox" id="symbols.box">
                             <property name="homogeneous">1</property>
                             <property name="selection-mode">none</property>
+                            <property name="max-children-per-line">10</property>
                             <signal name="child-activated" handler="emoji_activated"/>
                           </object>
                         </child>
@@ -152,6 +245,7 @@
                           <object class="GtkFlowBox" id="flags.box">
                             <property name="homogeneous">1</property>
                             <property name="selection-mode">none</property>
+                            <property name="max-children-per-line">10</property>
                             <signal name="child-activated" handler="emoji_activated"/>
                           </object>
                         </child>
@@ -161,84 +255,18 @@
                 </child>
                 <child>
                   <object class="GtkBox">
+                    <style>
+                      <class name="preview"/>
+                    </style>
                     <child>
-                      <object class="GtkButton" id="recent.button">
-                        <property name="relief">none</property>
-                        <style>
-                          <class name="emoji-section"/>
-                        </style>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkButton" id="people.button">
-                        <property name="relief">none</property>
-                        <style>
-                          <class name="emoji-section"/>
-                        </style>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkButton" id="body.button">
-                        <property name="relief">none</property>
-                        <style>
-                          <class name="emoji-section"/>
-                        </style>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkButton" id="nature.button">
-                        <property name="relief">none</property>
-                        <style>
-                          <class name="emoji-section"/>
-                        </style>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkButton" id="food.button">
-                        <property name="relief">none</property>
-                        <style>
-                          <class name="emoji-section"/>
-                        </style>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkButton" id="travel.button">
-                        <property name="relief">none</property>
-                        <style>
-                          <class name="emoji-section"/>
-                        </style>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkButton" id="activities.button">
-                        <property name="relief">none</property>
-                        <style>
-                          <class name="emoji-section"/>
-                        </style>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkButton" id="objects.button">
-                        <property name="relief">none</property>
-                        <style>
-                          <class name="emoji-section"/>
-                        </style>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkButton" id="symbols.button">
-                        <property name="relief">none</property>
+                      <object class="GtkLabel" id="emoji_preview">
                         <style>
-                          <class name="emoji-section"/>
+                          <class name="emoji"/>
                         </style>
                       </object>
                     </child>
                     <child>
-                      <object class="GtkButton" id="flags.button">
-                        <property name="relief">none</property>
-                        <style>
-                          <class name="emoji-section"/>
-                        </style>
+                      <object class="GtkLabel" id="emoji_name_preview">
                       </object>
                     </child>
                   </object>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]