[gnome-shell/uajain/st-entry-password-2: 8/8] StPasswordEntry: Add the peek-password-icon for show/hide passwords



commit e55dd716e24a0e7cf8cdf768117108ecdc080e30
Author: Umang Jain <mailumangjain gmail com>
Date:   Wed Dec 11 00:35:10 2019 +0530

    StPasswordEntry: Add the peek-password-icon for show/hide passwords
    
    Also introduce a "show-peek-icon" property to enable/disable
    the peek-password-icon in the password entry. This is useful
    in cases where the peeking the password functionality needs
    to be avoided.
    
    https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/619

 data/gnome-shell-theme.gresource.xml             |  2 +
 data/theme/eye-not-looking-symbolic.svg          |  4 ++
 data/theme/eye-open-negative-filled-symbolic.svg | 27 +++++++
 data/theme/gnome-shell-sass/_common.scss         |  5 ++
 src/st/st-password-entry.c                       | 91 ++++++++++++++++++++++--
 src/st/st-password-entry.h                       |  3 +
 6 files changed, 128 insertions(+), 4 deletions(-)
---
diff --git a/data/gnome-shell-theme.gresource.xml b/data/gnome-shell-theme.gresource.xml
index 21191f0ceb..cc9caef0a3 100644
--- a/data/gnome-shell-theme.gresource.xml
+++ b/data/gnome-shell-theme.gresource.xml
@@ -20,6 +20,8 @@
     <file>no-notifications.svg</file>
     <file>noise-texture.png</file>
     <file>pad-osd.css</file>
+    <file alias="icons/eye-open-negative-filled-symbolic.svg">eye-open-negative-filled-symbolic.svg</file>
+    <file alias="icons/eye-not-looking-symbolic.svg">eye-not-looking-symbolic.svg</file>
     <file alias="icons/pointer-double-click-symbolic.svg">pointer-double-click-symbolic.svg</file>
     <file alias="icons/pointer-drag-symbolic.svg">pointer-drag-symbolic.svg</file>
     <file alias="icons/pointer-primary-click-symbolic.svg">pointer-primary-click-symbolic.svg</file>
diff --git a/data/theme/eye-not-looking-symbolic.svg b/data/theme/eye-not-looking-symbolic.svg
new file mode 100644
index 0000000000..a168c87d8a
--- /dev/null
+++ b/data/theme/eye-not-looking-symbolic.svg
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg"; width="16" height="16">
+    <path d="M13.98 1.99a1 1 0 0 0-.687.303l-.984.984A8 8 0 0 0 8 2 8 8 0 0 0 .262 8.01a8 8 0 0 0 2.943 
4.37l-.912.913a1 1 0 1 0 1.414 1.414l11-11a1 1 0 0 0-.727-1.717zM8 4a4 4 0 0 1 2.611.974l-1.42 1.42A2 2 0 0 0 
8 6a2 2 0 0 0-2 2 2 2 0 0 0 .396 1.19l-1.42 1.42A4 4 0 0 1 4 8a4 4 0 0 1 4-4zm7.03 2.209l-3.344 3.343a4 4 0 0 
1-2.127 2.127l-2.28 2.28a8 8 0 0 0 .721.04 8 8 0 0 0 7.738-6.01 8 8 0 0 0-.709-1.78zm-7.53.79a.5.5 0 0 1 
.5.5.5.5 0 0 1-.5.5.5.5 0 0 1-.5-.5.5.5 0 0 1 .5-.5z" fill="#2e3436"/>
+</svg>
+
diff --git a/data/theme/eye-open-negative-filled-symbolic.svg 
b/data/theme/eye-open-negative-filled-symbolic.svg
new file mode 100644
index 0000000000..1e5351c991
--- /dev/null
+++ b/data/theme/eye-open-negative-filled-symbolic.svg
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"; xmlns:dc="http://purl.org/dc/elements/1.1/"; 
xmlns:cc="http://creativecommons.org/ns#"; xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"; 
xmlns:svg="http://www.w3.org/2000/svg"; xmlns="http://www.w3.org/2000/svg"; width="16" viewBox="0 0 16 16" 
version="1.1" id="svg7384" height="16">
+  <metadata id="metadata90">
+    <rdf:RDF>
+      <cc:Work rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+        <dc:title>Gnome Symbolic Icon Theme</dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <title id="title9167">Gnome Symbolic Icon Theme</title>
+  <defs id="defs7386">
+    <linearGradient osb:paint="solid" id="linearGradient7212">
+      <stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop7214"/>
+    </linearGradient>
+  </defs>
+  <g transform="translate(-341.0002,-13.000323)" style="display:inline" id="layer9"/>
+  <g transform="translate(-100,-380.00032)" id="layer1"/>
+  <g transform="translate(-100,-380.00032)" style="display:inline" id="layer10">
+    <path d="m 108,382 a 8,8 0 0 0 -7.73828,6.00977 A 8,8 0 0 0 108,394 8,8 0 0 0 115.73828,387.99023 8,8 0 
0 0 108,382 Z m 0,2 a 4,4 0 0 1 4,4 4,4 0 0 1 -4,4 4,4 0 0 1 -4,-4 4,4 0 0 1 4,-4 z" id="path2314" 
style="opacity:1;vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal"/>
+    <path id="path2318" d="m 110,388.00003 a 2,2 0 0 1 -2,2 2,2 0 0 1 -2,-2 2,2 0 0 1 2,-2 2,2 0 0 1 2,2 z" 
style="vector-effect:none;fill:#2e3436;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"/>
+  </g>
+  <g transform="translate(-100,-380.00032)" id="g6387"/>
+  <g transform="translate(-100,-380.00032)" id="layer11"/>
+</svg>
+
diff --git a/data/theme/gnome-shell-sass/_common.scss b/data/theme/gnome-shell-sass/_common.scss
index 8d203ada74..d4148306f9 100644
--- a/data/theme/gnome-shell-sass/_common.scss
+++ b/data/theme/gnome-shell-sass/_common.scss
@@ -97,6 +97,11 @@ StEntry {
     warning-color: $warning_color;
     padding: 0 4px;
   }
+
+  StIcon.peek-password {
+    icon-size: 1.09em;
+    padding: 0 4px;
+  }
 }
 
 
diff --git a/src/st/st-password-entry.c b/src/st/st-password-entry.c
index be8c926122..79793d28bc 100644
--- a/src/st/st-password-entry.c
+++ b/src/st/st-password-entry.c
@@ -19,6 +19,7 @@
 
 #include "st-private.h"
 #include "st-password-entry.h"
+#include "st-icon.h"
 
 #define BLACK_CIRCLE 9679
 
@@ -34,7 +35,9 @@ struct _StPasswordEntry
 
 struct _StPasswordEntryPrivate
 {
+  ClutterActor *peek_password_icon;
   gboolean      password_visible;
+  gboolean      show_peek_icon;
 };
 
 enum
@@ -42,6 +45,7 @@ enum
   PROP_0,
 
   PROP_PASSWORD_VISIBLE,
+  PROP_SHOW_PEEK_ICON,
 
   N_PROPS
 };
@@ -50,6 +54,15 @@ static GParamSpec *props[N_PROPS] = { NULL, };
 
 G_DEFINE_TYPE_WITH_PRIVATE (StPasswordEntry, st_password_entry, ST_TYPE_ENTRY);
 
+static void
+st_password_entry_secondary_icon_clicked (StEntry *entry)
+{
+  StPasswordEntry *password_entry = ST_PASSWORD_ENTRY (entry);
+  StPasswordEntryPrivate *priv = ST_PASSWORD_ENTRY_PRIV (password_entry);
+
+  st_password_entry_set_password_visible (password_entry, !priv->password_visible);
+}
+
 static void
 st_password_entry_get_property (GObject    *gobject,
                                 guint       prop_id,
@@ -63,7 +76,9 @@ st_password_entry_get_property (GObject    *gobject,
     case PROP_PASSWORD_VISIBLE:
       g_value_set_boolean (value, priv->password_visible);
       break;
-
+    case PROP_SHOW_PEEK_ICON:
+      g_value_set_boolean (value, priv->show_peek_icon);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
       break;
@@ -83,7 +98,9 @@ st_password_entry_set_property (GObject      *gobject,
     case PROP_PASSWORD_VISIBLE:
       st_password_entry_set_password_visible (entry, g_value_get_boolean (value));
       break;
-
+    case PROP_SHOW_PEEK_ICON:
+      st_password_entry_set_show_peek_icon (entry, g_value_get_boolean (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
       break;
@@ -94,16 +111,25 @@ static void
 st_password_entry_class_init (StPasswordEntryClass *klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  StEntryClass *st_entry_class = ST_ENTRY_CLASS (klass);
 
   gobject_class->get_property = st_password_entry_get_property;
   gobject_class->set_property = st_password_entry_set_property;
 
+  st_entry_class->secondary_icon_clicked = st_password_entry_secondary_icon_clicked;
+
   props[PROP_PASSWORD_VISIBLE] = g_param_spec_boolean ("password-visible",
                                                        "Password visible",
                                                        "Whether to text in the entry is masked or not",
                                                        FALSE,
                                                        ST_PARAM_READWRITE);
 
+  props[PROP_SHOW_PEEK_ICON] = g_param_spec_boolean ("show-peek-icon",
+                                                     "Show peek icon",
+                                                     "Whether to show the password peek icon",
+                                                     TRUE,
+                                                     ST_PARAM_READWRITE);
+
   g_object_class_install_properties (gobject_class, N_PROPS, props);
 }
 
@@ -125,10 +151,17 @@ clutter_text_password_char_cb (GObject    *object,
 static void
 st_password_entry_init (StPasswordEntry *entry)
 {
+  StPasswordEntryPrivate *priv = ST_PASSWORD_ENTRY_PRIV (entry);
   ClutterActor *clutter_text;
 
   st_entry_set_text (ST_ENTRY (entry), "");
 
+  priv->peek_password_icon = g_object_new (ST_TYPE_ICON,
+                                           "style-class", "peek-password",
+                                           "icon-name", "eye-not-looking-symbolic",
+                                           NULL);
+  st_entry_set_secondary_icon (ST_ENTRY (entry), priv->peek_password_icon);
+
   clutter_text = st_entry_get_clutter_text (ST_ENTRY (entry));
   clutter_text_set_password_char (CLUTTER_TEXT (clutter_text), BLACK_CIRCLE);
 
@@ -151,6 +184,50 @@ st_password_entry_new (void)
   return ST_ENTRY (g_object_new (ST_TYPE_PASSWORD_ENTRY, NULL));
 }
 
+/**
+ * st_password_entry_set_show_peek_icon:
+ * @entry: a #StPasswordEntry
+ * @value: #TRUE to show the peek-icon in the entry, #FALSE otherwise
+ *
+ * Sets whether to show or hide the peek-icon in the password entry.
+ */
+void
+st_password_entry_set_show_peek_icon (StPasswordEntry *entry, gboolean value)
+{
+  StPasswordEntryPrivate *priv;
+
+  g_return_if_fail (ST_IS_PASSWORD_ENTRY (entry));
+
+  priv = ST_PASSWORD_ENTRY_PRIV (entry);
+  if (priv->show_peek_icon == value)
+    return;
+
+  priv->show_peek_icon = value;
+  if (priv->show_peek_icon)
+    st_entry_set_secondary_icon (ST_ENTRY (entry), priv->peek_password_icon);
+  else
+    st_entry_set_secondary_icon (ST_ENTRY (entry), NULL);
+
+  g_object_notify_by_pspec (G_OBJECT (entry), props[PROP_SHOW_PEEK_ICON]);
+}
+
+/**
+ * st_password_entry_get_show_peek_icon:
+ * @entry: a #StPasswordEntry
+ *
+ * Gets whether peek-icon is shown or hidden in the password entry.
+ */
+gboolean
+st_password_entry_get_show_peek_icon (StPasswordEntry *entry)
+{
+  StPasswordEntryPrivate *priv;
+
+  g_return_val_if_fail (ST_IS_PASSWORD_ENTRY (entry), TRUE);
+
+  priv = ST_PASSWORD_ENTRY_PRIV (entry);
+  return priv->show_peek_icon;
+}
+
 /**
  * st_password_entry_set_password_visible:
  * @entry: a #StPasswordEntry
@@ -174,9 +251,15 @@ st_password_entry_set_password_visible (StPasswordEntry *entry, gboolean value)
 
   clutter_text = st_entry_get_clutter_text (ST_ENTRY (entry));
   if (priv->password_visible)
-    clutter_text_set_password_char (CLUTTER_TEXT (clutter_text), 0);
+    {
+      clutter_text_set_password_char (CLUTTER_TEXT (clutter_text), 0);
+      st_icon_set_icon_name (ST_ICON (priv->peek_password_icon), "eye-open-negative-filled-symbolic");
+    }
   else
-    clutter_text_set_password_char (CLUTTER_TEXT (clutter_text), BLACK_CIRCLE);
+    {
+      clutter_text_set_password_char (CLUTTER_TEXT (clutter_text), BLACK_CIRCLE);
+      st_icon_set_icon_name (ST_ICON (priv->peek_password_icon), "eye-not-looking-symbolic");
+    }
 
   g_object_notify_by_pspec (G_OBJECT (entry), props[PROP_PASSWORD_VISIBLE]);
 }
diff --git a/src/st/st-password-entry.h b/src/st/st-password-entry.h
index 44dd0b1935..3998068085 100644
--- a/src/st/st-password-entry.h
+++ b/src/st/st-password-entry.h
@@ -36,6 +36,9 @@ StEntry            *st_password_entry_new                        (void);
 gboolean            st_password_entry_get_password_visible       (StPasswordEntry *entry);
 void                st_password_entry_set_password_visible       (StPasswordEntry *entry,
                                                                   gboolean         value);
+gboolean            st_password_entry_get_show_peek_icon         (StPasswordEntry *entry);
+void                st_password_entry_set_show_peek_icon         (StPasswordEntry *entry,
+                                                                  gboolean         value);
 
 G_END_DECLS
 


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