[gnome-control-center/wip/feborges/new-users-panel: 1/17] user-accounts: Introduce users list carousel (UmCarousel)



commit aee189e3003802de306b0f2669b23fbdc1fbd047
Author: Felipe Borges <felipeborges gnome org>
Date:   Wed Jun 29 14:07:27 2016 +0200

    user-accounts: Introduce users list carousel (UmCarousel)
    
    https://bugzilla.gnome.org/show_bug.cgi?id=767065

 panels/user-accounts/Makefile.am                  |    4 +
 panels/user-accounts/data/carousel.ui             |   81 +++
 panels/user-accounts/data/user-accounts-dialog.ui |   91 +---
 panels/user-accounts/um-carousel.c                |  330 +++++++++++
 panels/user-accounts/um-carousel.h                |   25 +
 panels/user-accounts/um-user-panel.c              |  603 ++-------------------
 panels/user-accounts/user-accounts.gresource.xml  |    1 +
 7 files changed, 501 insertions(+), 634 deletions(-)
---
diff --git a/panels/user-accounts/Makefile.am b/panels/user-accounts/Makefile.am
index d473bc5..c77359d 100644
--- a/panels/user-accounts/Makefile.am
+++ b/panels/user-accounts/Makefile.am
@@ -36,6 +36,8 @@ libuser_accounts_la_SOURCES =         \
        pw-utils.h                      \
        pw-utils.c                      \
        um-photo-dialog.h               \
+       um-carousel.h                   \
+       um-carousel.c                   \
        um-photo-dialog.c               \
        cc-crop-area.h                  \
        cc-crop-area.c                  \
@@ -46,6 +48,8 @@ libuser_accounts_la_SOURCES =         \
        fingerprint-strings.h           \
        run-passwd.h                    \
        run-passwd.c                    \
+       um-carousel.h                   \
+       um-carousel.c                   \
        um-editable-button.h            \
        um-editable-button.c            \
        um-editable-combo.h             \
diff --git a/panels/user-accounts/data/carousel.ui b/panels/user-accounts/data/carousel.ui
new file mode 100644
index 0000000..56a0e37
--- /dev/null
+++ b/panels/user-accounts/data/carousel.ui
@@ -0,0 +1,81 @@
+<?xml version="1.0"?>
+<interface>
+  <!-- interface-requires gtk+ 3.8 -->
+  <template class="UmCarousel" parent="GtkGrid">
+    <property name="visible">True</property>
+    <child>
+      <object class="GtkOverlay">
+        <property name="visible">True</property>
+        <property name="expand">True</property>
+        <property name="border_width">15</property>
+        <child>
+          <object class="GtkStack" id="stack">
+            <property name="visible">True</property>
+            <property name="transition_type">slide-left</property>
+            <property name="transition_duration">400</property>
+            <style>
+              <class name="inline-toolbar"/>
+            </style>
+            <child>
+              <placeholder/>
+            </child>
+          </object>
+        </child>
+        <child type="overlay">
+          <object class="GtkBox">
+            <property name="visible">True</property>
+            <property name="orientation">horizontal</property>
+            <property name="border_width">12</property>
+            <child>
+              <object class="GtkButton" id="go_back_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="valign">center</property>
+                <style>
+                  <class name="circular"/>
+                </style>
+                <child>
+                  <object class="GtkImage">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="icon-size">4</property>
+                    <property name="icon_name">go-previous-symbolic</property>
+                  </object>
+                </child>
+                <signal name="clicked" handler="um_carousel_go_back_button_clicked" object="UmCarousel" 
swapped="no"/>
+              </object>
+              <packing>
+                <property name="pack_type">start</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="go_next_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="valign">center</property>
+                <style>
+                  <class name="circular"/>
+                </style>
+                <child>
+                  <object class="GtkImage">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="icon-size">4</property>
+                    <property name="icon_name">go-next-symbolic</property>
+                  </object>
+                </child>
+                <signal name="clicked" handler="um_carousel_go_next_button_clicked" object="UmCarousel" 
swapped="no"/>
+              </object>
+              <packing>
+                <property name="pack_type">end</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="pass-through">True</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/panels/user-accounts/data/user-accounts-dialog.ui 
b/panels/user-accounts/data/user-accounts-dialog.ui
index bb68c97..5b74063 100644
--- a/panels/user-accounts/data/user-accounts-dialog.ui
+++ b/panels/user-accounts/data/user-accounts-dialog.ui
@@ -21,90 +21,22 @@
           <object class="GtkVBox" id="accounts-vbox">
             <property name="visible">True</property>
             <property name="orientation">vertical</property>
-            <property name="border_width">12</property>
+            <property name="border_width">0</property>
             <child>
-              <object class="GtkHBox" id="hbox2">
+              <object class="UmCarousel" id="carousel">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkFrame" id="hbox2">
                 <property name="visible">True</property>
-                <property name="spacing">18</property>
-                <child>
-                  <object class="GtkVBox" id="userlist-vbox">
-                    <property name="visible">True</property>
-                    <property name="orientation">vertical</property>
-                    <property name="spacing">0</property>
-                    <child>
-                      <object class="GtkScrolledWindow" id="list-scrolledwindow">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="hscrollbar_policy">never</property>
-                        <property name="vscrollbar_policy">automatic</property>
-                        <property name="shadow_type">in</property>
-                        <child>
-                          <object class="GtkTreeView" id="list-treeview">
-                            <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="headers_visible">False</property>
-                          </object>
-                        </child>
-                      </object>
-                      <packing>
-                        <property name="expand">True</property>
-                        <property name="fill">True</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkToolbar" id="add-remove-toolbar">
-                        <property name="visible">True</property>
-                        <property name="icon_size">1</property>
-                        <property name="icon_size_set">True</property>
-                        <property name="toolbar_style">icons</property>
-                        <style>
-                          <class name="inline-toolbar"/>
-                        </style>
-                        <child>
-                          <object class="GtkToolButton" id="add-user-toolbutton">
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="icon_name">list-add-symbolic</property>
-                            <property name="label" translatable="yes">Add User Account</property>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="homogeneous">True</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <object class="GtkToolButton" id="remove-user-toolbutton">
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="icon_name">list-remove-symbolic</property>
-                            <property name="label" translatable="yes">Remove User Account</property>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="homogeneous">True</property>
-                          </packing>
-                        </child>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
                 <child>
                   <object class="GtkVBox" id="main-user-vbox">
                     <property name="visible">True</property>
-                    <property name="sensitive">False</property>
                     <property name="orientation">vertical</property>
                     <property name="spacing">6</property>
+                    <property name="border_width">24</property>
                     <child>
                       <object class="GtkGrid" id="grid1">
                         <property name="visible">True</property>
@@ -478,11 +410,6 @@
                       </packing>
                     </child>
                   </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
                 </child>
               </object>
             </child>
diff --git a/panels/user-accounts/um-carousel.c b/panels/user-accounts/um-carousel.c
new file mode 100644
index 0000000..6bf7037
--- /dev/null
+++ b/panels/user-accounts/um-carousel.c
@@ -0,0 +1,330 @@
+#include "um-carousel.h"
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#define ITEMS_PER_PAGE 3
+
+typedef struct {
+        GSequence *pages;
+       GSequence *children;
+        gint current_page;
+
+        GList *model;
+        UmCarouselCreateWidgetFunc create_widget_func;
+        gpointer create_widget_func_data;
+        GDestroyNotify create_widget_func_data_destroy;
+
+        /* Widgets */
+        GtkStack *stack;
+        GtkRadioButton *current_button;
+} UmCarouselPrivate;
+
+struct _UmCarousel {
+        GtkGrid parent;
+
+        UmCarouselPrivate *priv;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (UmCarousel, um_carousel, GTK_TYPE_GRID)
+
+enum {
+        ITEM_ACTIVATED,
+        NUM_SIGNALS
+};
+
+static guint signals[NUM_SIGNALS] = { 0, };
+
+static GtkWidget *
+get_page (UmCarousel *self)
+{
+        UmCarouselPrivate *priv;
+        GSequenceIter *iter = NULL;
+        GtkWidget *box;
+        gint num_of_children;
+
+        priv = self->priv;
+
+       num_of_children = g_sequence_get_length (priv->children);
+        if (num_of_children % ITEMS_PER_PAGE == 0) {
+               gchar *page_name;
+
+                box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+                page_name = g_strdup_printf ("%d", g_sequence_get_length (priv->pages));
+                gtk_stack_add_named (priv->stack, box, page_name);
+
+                g_sequence_append (priv->pages, box);
+        } else {
+                iter = g_sequence_get_end_iter (priv->pages);
+                iter = g_sequence_iter_prev (iter);
+                box = g_sequence_get (iter);
+        }
+
+        return box;
+}
+
+static void
+on_item_toggled (GtkToggleButton *item,
+                 gpointer         user_data)
+{
+        g_signal_emit (user_data, signals[ITEM_ACTIVATED], 0, item);
+}
+
+static GtkWidget *
+create_item (UmCarousel *self,
+             GtkWidget  *child,
+             gint        position)
+{
+        UmCarouselPrivate *priv;
+        GtkWidget *item;
+
+        priv = self->priv;
+
+        item = gtk_radio_button_new (NULL);
+        g_signal_connect (item, "toggled", G_CALLBACK (on_item_toggled), self);
+        g_object_set_data (G_OBJECT (item), "position", GINT_TO_POINTER (position));
+
+        if (priv->current_button == NULL) {
+                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), TRUE);
+        }
+        else {
+                gtk_radio_button_join_group (GTK_RADIO_BUTTON (item), priv->current_button);
+        }
+        priv->current_button = GTK_RADIO_BUTTON (item);
+
+        gtk_container_add (GTK_CONTAINER (item), child);
+        gtk_widget_show (GTK_WIDGET (item));
+
+        gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (item), FALSE);
+        gtk_style_context_add_class (gtk_widget_get_style_context (item), "flat");
+        gtk_widget_set_valign (item, GTK_ALIGN_CENTER);
+
+        return item;
+}
+
+static void
+forall_items (GtkContainer *container,
+              GtkCallback   callback,
+              gpointer      callback_target)
+{
+        UmCarouselPrivate *priv = UM_CAROUSEL (container)->priv;
+        GSequenceIter *iter;
+        GtkWidget *item;
+
+        iter = g_sequence_get_begin_iter (priv->children);
+        while (!g_sequence_iter_is_end (iter)) {
+                item = g_sequence_get (iter);
+                iter = g_sequence_iter_next (iter);
+                callback (GTK_WIDGET (item), callback_target);
+        }
+}
+
+static GtkWidget *
+get_item_at_index (UmCarousel *self,
+                  gint        index)
+{
+        UmCarouselPrivate *priv = self->priv;
+        GSequenceIter *iter;
+
+        iter = g_sequence_get_iter_at_pos (priv->children, index);
+        if (!g_sequence_iter_is_end (iter))
+                return g_sequence_get (iter);
+
+        return NULL;
+}
+
+static void
+insert_item (UmCarousel *self,
+             GtkWidget  *child,
+             gint        position)
+{
+        UmCarouselPrivate *priv;
+        GtkWidget *item, *box;
+
+        priv = self->priv;
+
+        box = get_page (self);
+        item = create_item (self, child, position);
+
+        if (position == 0) {
+                g_sequence_prepend (priv->children, item);
+                gtk_box_pack_start (GTK_BOX (box), item, TRUE, FALSE, 10);
+        }
+        else if (position == -1) {
+                g_sequence_append (priv->children, item);
+                gtk_box_pack_end (GTK_BOX (box), item, TRUE, FALSE, 10);
+        }
+        else {
+                GSequenceIter *iter;
+
+                iter = g_sequence_get_iter_at_pos (priv->children, position);
+                iter = g_sequence_insert_before (iter, item);
+
+                gtk_box_pack_start (GTK_BOX (box), item, TRUE, FALSE, 10);
+                gtk_box_reorder_child (GTK_BOX (box), item, position);
+        }
+
+        gtk_widget_show_all (box);
+}
+
+static void
+model_changed (GListModel *list,
+               guint       position,
+               guint       removed,
+               guint       added,
+               gpointer    user_data)
+{
+        UmCarousel *self = user_data;
+        UmCarouselPrivate *priv = self->priv;
+        gint i;
+
+        while (removed--) {
+                GtkWidget *item;
+
+                item = get_item_at_index (self, position);
+                gtk_widget_destroy (GTK_WIDGET (item));
+        }
+
+        for (i = 0; i < added; i++) {
+                GObject *item;
+                GtkWidget *widget;
+
+                item = g_list_model_get_item (list, position + i);
+                widget = priv->create_widget_func (item, priv->create_widget_func_data);
+
+                if (g_object_is_floating (widget))
+                        g_object_ref_sink (widget);
+
+                gtk_widget_show (widget);
+                insert_item (self, widget, position + i);
+
+                g_object_unref (widget);
+                g_object_unref (item);
+        }
+}
+
+void
+um_carousel_bind_model (UmCarousel    *self,
+                        GListModel    *model,
+                        UmCarouselCreateWidgetFunc create_widget_func,
+                        gpointer user_data,
+                        GDestroyNotify user_data_free_func)
+{
+        UmCarouselPrivate *priv;
+
+        priv = self->priv;
+
+        if (priv->model) {
+                if (priv->create_widget_func_data_destroy) {
+                        priv->create_widget_func_data_destroy (priv->create_widget_func_data);
+                }
+
+                g_signal_handlers_disconnect_by_func (priv->model, model_changed, self);
+                g_clear_object (&priv->model);
+        }
+
+        forall_items (GTK_CONTAINER (self), (GtkCallback) gtk_widget_destroy, NULL);
+
+        if (model == NULL)
+                return;
+
+        priv->model = g_object_ref (model);
+        priv->create_widget_func = create_widget_func;
+        priv->create_widget_func_data = user_data;
+        priv->create_widget_func_data_destroy = user_data_free_func;
+
+        g_signal_connect (priv->model, "items-changed", G_CALLBACK (model_changed), self);
+        model_changed (model, 0, 0, g_list_model_get_n_items (model), self);
+}
+
+static void
+um_carousel_go_back_button_clicked (GtkButton *button,
+                                    gpointer   user_data)
+{
+        UmCarouselPrivate *priv;
+        gchar *page_name;
+
+        priv = UM_CAROUSEL (user_data)->priv;
+
+        priv->current_page--;
+        if (priv->current_page < 0)
+                priv->current_page = g_sequence_get_length (priv->pages) - 1;
+
+        page_name = g_strdup_printf ("%d", priv->current_page);
+        gtk_stack_set_visible_child_name (priv->stack, page_name);
+        /* TODO: handle no more pages and such */
+}
+
+static void
+um_carousel_go_next_button_clicked (GtkButton *button,
+                                    gpointer   user_data)
+{
+        UmCarouselPrivate *priv;
+        gchar *page_name;
+
+        priv = UM_CAROUSEL (user_data)->priv;
+
+        priv->current_page++;
+        if (priv->current_page >= g_sequence_get_length (priv->pages))
+                priv->current_page = 0;
+
+        page_name = g_strdup_printf ("%d", priv->current_page);
+        gtk_stack_set_visible_child_name (priv->stack, page_name);
+        /* TODO: handle no more pages and such */
+}
+
+UmCarousel *
+um_carousel_new (void)
+{
+        return g_object_new (UM_TYPE_CAROUSEL, NULL);
+}
+
+static void
+um_carousel_finalize (GObject *object)
+{
+        UmCarousel *self = (UmCarousel *)object;
+
+        G_OBJECT_CLASS (um_carousel_parent_class)->finalize (object);
+}
+
+static void
+um_carousel_class_init (UmCarouselClass *klass)
+{
+        GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+        GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+        object_class->finalize = um_carousel_finalize;
+
+        gtk_widget_class_set_template_from_resource (widget_class,
+                                                     "/org/gnome/control-center/user-accounts/carousel.ui");
+
+        gtk_widget_class_bind_template_child_private (widget_class, UmCarousel, stack);
+
+        gtk_widget_class_bind_template_callback (widget_class, um_carousel_go_back_button_clicked);
+        gtk_widget_class_bind_template_callback (widget_class, um_carousel_go_next_button_clicked);
+
+        signals[ITEM_ACTIVATED] = g_signal_new ("item-activated",
+                                                UM_TYPE_CAROUSEL,
+                                                G_SIGNAL_RUN_LAST,
+                                                0,
+                                                NULL, NULL,
+                                                g_cclosure_marshal_VOID__OBJECT,
+                                                G_TYPE_NONE, 1,
+                                                GTK_TYPE_TOGGLE_BUTTON);
+}
+
+static void
+um_carousel_init (UmCarousel *self)
+{
+        UmCarouselPrivate *priv = um_carousel_get_instance_private (self);
+
+        self->priv = priv;
+
+        priv->pages = g_sequence_new (NULL);
+        priv->current_page = 0;
+        priv->children = g_sequence_new (NULL);
+
+        gtk_widget_init_template (GTK_WIDGET (self));
+
+        priv->current_button = NULL;
+}
diff --git a/panels/user-accounts/um-carousel.h b/panels/user-accounts/um-carousel.h
new file mode 100644
index 0000000..e8e93b2
--- /dev/null
+++ b/panels/user-accounts/um-carousel.h
@@ -0,0 +1,25 @@
+#ifndef UM_CAROUSEL_H
+#define UM_CAROUSEL_H
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define UM_TYPE_CAROUSEL (um_carousel_get_type())
+
+G_DECLARE_FINAL_TYPE (UmCarousel, um_carousel, UM, CAROUSEL, GtkGrid)
+
+typedef GtkWidget * (*UmCarouselCreateWidgetFunc) (gpointer item,
+                                                  gpointer user_data);
+
+UmCarousel *um_carousel_new                (void);
+void        um_carousel_bind_model         (UmCarousel    *self,
+                                           GListModel    *model,
+                                           UmCarouselCreateWidgetFunc create_widget_func,
+                                           gpointer user_data,
+                                           GDestroyNotify user_data_free_func);
+
+G_END_DECLS
+
+#endif /* UM_CAROUSEL_H */
diff --git a/panels/user-accounts/um-user-panel.c b/panels/user-accounts/um-user-panel.c
index 2b6ea7e..f323a04 100644
--- a/panels/user-accounts/um-user-panel.c
+++ b/panels/user-accounts/um-user-panel.c
@@ -45,6 +45,7 @@
 #include "um-editable-combo.h"
 #include "um-user-image.h"
 #include "um-cell-renderer-user-image.h"
+#include "um-carousel.h"
 
 #include "um-account-dialog.h"
 #include "cc-language-chooser.h"
@@ -74,6 +75,7 @@ struct _CcUserPanelPrivate {
         GtkWidget *notification;
         GSettings *login_screen_settings;
 
+        UmCarousel *carousel;
         GtkWidget *main_box;
         GPermission *permission;
         GtkWidget *language_chooser;
@@ -83,7 +85,8 @@ struct _CcUserPanelPrivate {
         UmHistoryDialog *history_dialog;
 
         gint other_accounts;
-        GtkTreeIter *other_iter;
+        GListStore *users_list;
+        ActUser *selected_user;
 
         UmAccountDialog *account_dialog;
 };
@@ -94,16 +97,6 @@ get_widget (CcUserPanelPrivate *d, const char *name)
         return (GtkWidget *)gtk_builder_get_object (d->builder, name);
 }
 
-enum {
-        USER_COL,
-        NAME_COL,
-        USER_ROW_COL,
-        TITLE_COL,
-        HEADING_ROW_COL,
-        SORT_KEY_COL,
-        NUM_USER_LIST_COLS
-};
-
 static void show_restart_notification (CcUserPanelPrivate *d, const gchar *locale);
 
 typedef struct {
@@ -147,21 +140,7 @@ show_error_dialog (CcUserPanelPrivate *d,
 static ActUser *
 get_selected_user (CcUserPanelPrivate *d)
 {
-        GtkTreeView *tv;
-        GtkTreeIter iter;
-        GtkTreeSelection *selection;
-        GtkTreeModel *model;
-        ActUser *user;
-
-        tv = (GtkTreeView *)get_widget (d, "list-treeview");
-        selection = gtk_tree_view_get_selection (tv);
-
-        if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
-                gtk_tree_model_get (model, &iter, USER_COL, &user, -1);
-                return user;
-        }
-
-        return NULL;
+        return d->selected_user;
 }
 
 static const gchar *
@@ -176,205 +155,66 @@ get_real_or_user_name (ActUser *user)
   return name;
 }
 
-static char *
-get_name_col_str (ActUser *user)
-{
-        return g_markup_printf_escaped ("<b>%s</b>\n<small>%s</small>",
-                                        get_real_or_user_name (user),
-                                        act_user_get_user_name (user));
-}
+static void show_user (ActUser *user, CcUserPanelPrivate *d);
 
 static void
-user_added (ActUserManager *um, ActUser *user, CcUserPanelPrivate *d)
+item_toggled (UmCarousel *carousel,
+              GtkToggleButton *item,
+              CcUserPanelPrivate *d)
 {
-        GtkWidget *widget;
-        GtkTreeModel *model;
-        GtkListStore *store;
-        GtkTreeIter iter;
-        GtkTreeIter dummy;
-        gchar *text, *title;
-        GtkTreeSelection *selection;
-        gint sort_key;
+        ActUser *user;
+        gint position;
 
-        if (act_user_is_system_account (user)) {
-                return;
+        position = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item), "position"));
+        user = g_list_model_get_item (G_LIST_MODEL (d->users_list), position);
+
+        if (ACT_IS_USER (user)) {
+                d->selected_user = user;
+                show_user (user, d);
         }
+}
 
-        g_debug ("user added: %d %s\n", act_user_get_uid (user), get_real_or_user_name (user));
-        widget = get_widget (d, "list-treeview");
-        model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
-        store = GTK_LIST_STORE (model);
-        selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
+static GtkWidget *
+create_user_item (gpointer item,
+                  gpointer user_data)
+{
+        ActUser *user = ACT_USER (item);
+        GtkWidget *widget, *grid;
 
-        text = get_name_col_str (user);
+        grid = gtk_grid_new ();
+        gtk_grid_set_row_spacing (GTK_GRID (grid), 12);
+        widget = um_user_image_new ();
+        um_user_image_set_user (UM_USER_IMAGE (widget), user);
+        gtk_grid_attach (GTK_GRID (grid), widget, 0, 0, 1, 1);
 
-        if (act_user_get_uid (user) == getuid ()) {
-                sort_key = 1;
-        }
-        else {
-                d->other_accounts++;
-                sort_key = 3;
-        }
-        gtk_list_store_append (store, &iter);
-
-        gtk_list_store_set (store, &iter,
-                            USER_COL, user,
-                            NAME_COL, text,
-                            USER_ROW_COL, TRUE,
-                            TITLE_COL, NULL,
-                            HEADING_ROW_COL, FALSE,
-                            SORT_KEY_COL, sort_key,
-                            -1);
-        g_free (text);
-
-        if (sort_key == 1 &&
-            !gtk_tree_selection_get_selected (selection, &model, &dummy)) {
-                gtk_tree_selection_select_iter (selection, &iter);
-        }
+        widget = gtk_label_new (get_real_or_user_name (user));
+        gtk_grid_attach (GTK_GRID (grid), widget, 0, 1, 1, 1);
 
-        /* Show heading for other accounts if new one have been added. */
-        if (d->other_accounts == 1 && sort_key == 3) {
-                title = g_strdup_printf ("<small><span foreground=\"#555555\">%s</span></small>", _("Other 
Accounts"));
-                gtk_list_store_append (store, &iter);
-                gtk_list_store_set (store, &iter,
-                                    TITLE_COL, title,
-                                    HEADING_ROW_COL, TRUE,
-                                    SORT_KEY_COL, 2,
-                                    -1);
-                d->other_iter = gtk_tree_iter_copy (&iter);
-                g_free (title);
-        }
+        return grid;
 }
 
 static void
-get_previous_user_row (GtkTreeModel *model,
-                       GtkTreeIter  *iter,
-                       GtkTreeIter  *prev)
+user_added (ActUserManager *um, ActUser *user, CcUserPanelPrivate *d)
 {
-        GtkTreePath *path;
-        ActUser *user;
-
-        path = gtk_tree_model_get_path (model, iter);
-        while (gtk_tree_path_prev (path)) {
-                gtk_tree_model_get_iter (model, prev, path);
-                gtk_tree_model_get (model, prev, USER_COL, &user, -1);
-                if (user) {
-                        g_object_unref (user);
-                        break;
-                }
+        if (act_user_is_system_account (user)) {
+                return;
         }
-        gtk_tree_path_free (path);
-}
 
-static gboolean
-get_next_user_row (GtkTreeModel *model,
-                   GtkTreeIter  *iter,
-                   GtkTreeIter  *next)
-{
-        ActUser *user;
-
-        *next = *iter;
-        while (gtk_tree_model_iter_next (model, next)) {
-                gtk_tree_model_get (model, next, USER_COL, &user, -1);
-                if (user) {
-                        g_object_unref (user);
-                        return TRUE;
-                }
-        }
+        g_debug ("user added: %d %s\n", act_user_get_uid (user), get_real_or_user_name (user));
 
-        return FALSE;
+        g_list_store_append (d->users_list, user);
 }
 
 static void
 user_removed (ActUserManager *um, ActUser *user, CcUserPanelPrivate *d)
 {
-        GtkTreeView *tv;
-        GtkTreeModel *model;
-        GtkTreeSelection *selection;
-        GtkListStore *store;
-        GtkTreeIter iter, next;
-        ActUser *u;
-        gint key;
-
-        g_debug ("user removed: %s\n", act_user_get_user_name (user));
-        tv = (GtkTreeView *)get_widget (d, "list-treeview");
-        selection = gtk_tree_view_get_selection (tv);
-        model = gtk_tree_view_get_model (tv);
-        store = GTK_LIST_STORE (model);
-        if (gtk_tree_model_get_iter_first (model, &iter)) {
-                do {
-                        gtk_tree_model_get (model, &iter, USER_COL, &u, SORT_KEY_COL, &key, -1);
-
-                        if (u != NULL) {
-                                if (act_user_get_uid (user) == act_user_get_uid (u)) {
-                                        if (!get_next_user_row (model, &iter, &next))
-                                                get_previous_user_row (model, &iter, &next);
-                                        if (key == 3) {
-                                                d->other_accounts--;
-                                        }
-                                        gtk_list_store_remove (store, &iter);
-                                        gtk_tree_selection_select_iter (selection, &next);
-                                        g_object_unref (u);
-                                        break;
-                                }
-                                g_object_unref (u);
-                        }
-                } while (gtk_tree_model_iter_next (model, &iter));
-        }
-
-        /* Hide heading for other accounts if last one have been removed. */
-        if (d->other_iter != NULL && d->other_accounts == 0 && key == 3) {
-                gtk_list_store_remove (store, d->other_iter);
-                gtk_tree_iter_free (d->other_iter);
-                d->other_iter = NULL;
-        }
+        g_print ("user removed\n");
 }
 
-static void show_user (ActUser *user, CcUserPanelPrivate *d);
-
 static void
 user_changed (ActUserManager *um, ActUser *user, CcUserPanelPrivate *d)
 {
-        GtkTreeView *tv;
-        GtkTreeSelection *selection;
-        GtkTreeModel *model;
-        GtkTreeIter iter;
-        ActUser *current;
-        char *text;
-
-        tv = (GtkTreeView *)get_widget (d, "list-treeview");
-        model = gtk_tree_view_get_model (tv);
-        selection = gtk_tree_view_get_selection (tv);
-
-        g_assert (gtk_tree_model_get_iter_first (model, &iter));
-        do {
-                gtk_tree_model_get (model, &iter, USER_COL, &current, -1);
-                if (current == user) {
-                        text = get_name_col_str (user);
-
-                        gtk_list_store_set (GTK_LIST_STORE (model), &iter,
-                                            USER_COL, user,
-                                            NAME_COL, text,
-                                            -1);
-                        g_free (text);
-                        g_object_unref (current);
-
-                        break;
-                }
-                if (current)
-                        g_object_unref (current);
-
-        } while (gtk_tree_model_iter_next (model, &iter));
-
-        if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
-                gtk_tree_model_get (model, &iter, USER_COL, &current, -1);
-
-                if (current == user) {
-                        show_user (user, d);
-                }
-                if (current)
-                        g_object_unref (current);
-        }
+        g_print ("user changed\n");
 }
 
 static void
@@ -384,12 +224,7 @@ select_created_user (GObject *object,
 {
         CcUserPanelPrivate *d = user_data;
         UmAccountDialog *dialog;
-        GtkTreeView *tv;
-        GtkTreeModel *model;
-        GtkTreeSelection *selection;
-        GtkTreeIter iter;
         ActUser *current;
-        GtkTreePath *path;
         ActUser *user;
         uid_t user_uid;
 
@@ -401,27 +236,7 @@ select_created_user (GObject *object,
         if (user == NULL)
                 return;
 
-        tv = (GtkTreeView *)get_widget (d, "list-treeview");
-        model = gtk_tree_view_get_model (tv);
-        selection = gtk_tree_view_get_selection (tv);
         user_uid = act_user_get_uid (user);
-
-        g_assert (gtk_tree_model_get_iter_first (model, &iter));
-        do {
-                gtk_tree_model_get (model, &iter, USER_COL, &current, -1);
-                if (current) {
-                        if (user_uid == act_user_get_uid (current)) {
-                                path = gtk_tree_model_get_path (model, &iter);
-                                gtk_tree_view_scroll_to_cell (tv, path, NULL, FALSE, 0.0, 0.0);
-                                gtk_tree_selection_select_path (selection, path);
-                                gtk_tree_path_free (path);
-                                g_object_unref (current);
-                                break;
-                        }
-                        g_object_unref (current);
-                }
-        } while (gtk_tree_model_iter_next (model, &iter));
-
         g_object_unref (user);
 }
 
@@ -868,6 +683,7 @@ get_autologin_possible (ActUser *user)
 }
 
 static void on_permission_changed (GPermission *permission, GParamSpec *pspec, gpointer data);
+static void account_type_changed (GtkToggleButton    *button, CcUserPanelPrivate *d);
 
 static void
 show_user (ActUser *user, CcUserPanelPrivate *d)
@@ -888,10 +704,11 @@ show_user (ActUser *user, CcUserPanelPrivate *d)
 
         widget = get_widget (d, "full-name-entry");
         cc_editable_entry_set_text (CC_EDITABLE_ENTRY (widget), act_user_get_real_name (user));
-        gtk_widget_set_tooltip_text (widget, act_user_get_user_name (user));
 
         widget = get_widget (d, act_user_get_account_type (user) ? "account-type-admin" : 
"account-type-standard");
+        g_signal_handlers_block_by_func (widget, account_type_changed, d);
         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
+        g_signal_handlers_unblock_by_func (widget, account_type_changed, d);
 
         widget = get_widget (d, "account-type-static");
         if (act_user_get_account_type (user) == ACT_USER_ACCOUNT_TYPE_ADMINISTRATOR)
@@ -978,23 +795,6 @@ show_user (ActUser *user, CcUserPanelPrivate *d)
 }
 
 static void
-selected_user_changed (GtkTreeSelection *selection, CcUserPanelPrivate *d)
-{
-        GtkTreeModel *model;
-        GtkTreeIter iter;
-        ActUser *user;
-
-        if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
-                gtk_tree_model_get (model, &iter, USER_COL, &user, -1);
-                show_user (user, d);
-                gtk_widget_set_sensitive (get_widget (d, "main-user-vbox"), TRUE);
-                g_object_unref (user);
-        } else {
-                gtk_widget_set_sensitive (get_widget (d, "main-user-vbox"), FALSE);
-        }
-}
-
-static void
 change_name_done (GtkWidget          *entry,
                   CcUserPanelPrivate *d)
 {
@@ -1217,55 +1017,6 @@ show_history (GtkButton *button, CcUserPanelPrivate *d)
         g_object_unref (user);
 }
 
-static gint
-sort_users (GtkTreeModel *model,
-            GtkTreeIter  *a,
-            GtkTreeIter  *b,
-            gpointer      data)
-{
-        ActUser *ua, *ub;
-        gint sa, sb;
-        gint result;
-
-        gtk_tree_model_get (model, a, USER_COL, &ua, SORT_KEY_COL, &sa, -1);
-        gtk_tree_model_get (model, b, USER_COL, &ub, SORT_KEY_COL, &sb, -1);
-
-        if (sa < sb) {
-                result = -1;
-        }
-        else if (sa > sb) {
-                result = 1;
-        }
-        else {
-                result = act_user_collate (ua, ub);
-        }
-
-        if (ua) {
-                g_object_unref (ua);
-        }
-        if (ub) {
-                g_object_unref (ub);
-        }
-
-        return result;
-}
-
-static gboolean
-dont_select_headings (GtkTreeSelection *selection,
-                      GtkTreeModel     *model,
-                      GtkTreePath      *path,
-                      gboolean          selected,
-                      gpointer          data)
-{
-        GtkTreeIter iter;
-        gboolean is_user;
-
-        gtk_tree_model_get_iter (model, &iter, path);
-        gtk_tree_model_get (model, &iter, USER_ROW_COL, &is_user, -1);
-
-        return is_user;
-}
-
 static void
 users_loaded (ActUserManager     *manager,
               GParamSpec         *pspec,
@@ -1309,37 +1060,6 @@ users_loaded (ActUserManager     *manager,
 }
 
 static void
-add_unlock_tooltip (GtkWidget *button)
-{
-        gchar *names[3];
-        GIcon *icon;
-
-        names[0] = "changes-allow-symbolic";
-        names[1] = "changes-allow";
-        names[2] = NULL;
-        icon = (GIcon *)g_themed_icon_new_from_names (names, -1);
-        /* Translator comments:
-         * We split the line in 2 here to "make it look good", as there's
-         * no good way to do this in GTK+ for tooltips. See:
-         * https://bugzilla.gnome.org/show_bug.cgi?id=657168 */
-        setup_tooltip_with_embedded_icon (button,
-                                          _("To make changes,\nclick the * icon first"),
-                                          "*",
-                                          icon);
-        g_object_unref (icon);
-        g_signal_connect (button, "button-release-event",
-                           G_CALLBACK (show_tooltip_now), NULL);
-}
-
-static void
-remove_unlock_tooltip (GtkWidget *button)
-{
-        setup_tooltip_with_embedded_icon (button, NULL, NULL, NULL);
-        g_signal_handlers_disconnect_by_func (button,
-                                              G_CALLBACK (show_tooltip_now), NULL);
-}
-
-static void
 on_permission_changed (GPermission *permission,
                        GParamSpec  *pspec,
                        gpointer     data)
@@ -1358,53 +1078,9 @@ on_permission_changed (GPermission *permission,
         is_authorized = g_permission_get_allowed (G_PERMISSION (d->permission));
         self_selected = act_user_get_uid (user) == geteuid ();
 
-        widget = get_widget (d, "add-user-toolbutton");
-        gtk_widget_set_sensitive (widget, is_authorized);
-        if (is_authorized) {
-                setup_tooltip_with_embedded_icon (widget, _("Create a user account"), NULL, NULL);
-        }
-        else {
-                gchar *names[3];
-                GIcon *icon;
-
-                names[0] = "changes-allow-symbolic";
-                names[1] = "changes-allow";
-                names[2] = NULL;
-                icon = (GIcon *)g_themed_icon_new_from_names (names, -1);
-                setup_tooltip_with_embedded_icon (widget,
-                                                  _("To create a user account,\nclick the * icon first"),
-                                                  "*",
-                                                  icon);
-                g_object_unref (icon);
-        }
-
-        widget = get_widget (d, "remove-user-toolbutton");
-        gtk_widget_set_sensitive (widget, is_authorized && !self_selected
-                                  && !would_demote_only_admin (user));
-        if (is_authorized) {
-                setup_tooltip_with_embedded_icon (widget, _("Delete the selected user account"), NULL, NULL);
-        }
-        else {
-                gchar *names[3];
-                GIcon *icon;
-
-                names[0] = "changes-allow-symbolic";
-                names[1] = "changes-allow";
-                names[2] = NULL;
-                icon = (GIcon *)g_themed_icon_new_from_names (names, -1);
-
-                setup_tooltip_with_embedded_icon (widget,
-                                                  _("To delete the selected user account,\nclick the * icon 
first"),
-                                                  "*",
-                                                  icon);
-                g_object_unref (icon);
-        }
-
         if (!act_user_is_local_account (user)) {
                 gtk_stack_set_visible_child_name (GTK_STACK (get_widget (d, "account-type-stack")), 
"static");
-                remove_unlock_tooltip (get_widget (d, "account-type-stack"));
                 gtk_widget_set_sensitive (GTK_WIDGET (get_widget (d, "autologin-switch")), FALSE);
-                remove_unlock_tooltip (get_widget (d, "autologin-switch"));
 
         } else if (is_authorized && act_user_is_local_account (user)) {
                 if (would_demote_only_admin (user)) {
@@ -1412,35 +1088,24 @@ on_permission_changed (GPermission *permission,
                 } else {
                         gtk_stack_set_visible_child_name (GTK_STACK (get_widget (d, "account-type-stack")), 
"buttons");
                 }
-                remove_unlock_tooltip (get_widget (d, "account-type-stack"));
 
                 gtk_widget_set_sensitive (GTK_WIDGET (get_widget (d, "autologin-switch")), 
get_autologin_possible (user));
-                remove_unlock_tooltip (get_widget (d, "autologin-switch"));
         }
         else {
                 gtk_stack_set_visible_child_name (GTK_STACK (get_widget (d, "account-type-stack")), 
"static");
-                if (would_demote_only_admin (user)) {
-                        remove_unlock_tooltip (get_widget (d, "account-type-stack"));
-                } else {
-                        add_unlock_tooltip (get_widget (d, "account-type-stack"));
-                }
                 gtk_widget_set_sensitive (GTK_WIDGET (get_widget (d, "autologin-switch")), FALSE);
-                add_unlock_tooltip (get_widget (d, "autologin-switch"));
         }
 
         /* The full name entry: insensitive if remote or not authorized and not self */
         widget = get_widget (d, "full-name-entry");
         if (!act_user_is_local_account (user)) {
                 cc_editable_entry_set_editable (CC_EDITABLE_ENTRY (widget), FALSE);
-                remove_unlock_tooltip (widget);
 
         } else if (is_authorized || self_selected) {
                 cc_editable_entry_set_editable (CC_EDITABLE_ENTRY (widget), TRUE);
-                remove_unlock_tooltip (widget);
 
         } else {
                 cc_editable_entry_set_editable (CC_EDITABLE_ENTRY (widget), FALSE);
-                add_unlock_tooltip (widget);
         }
 
         if (is_authorized || self_selected) {
@@ -1448,26 +1113,16 @@ on_permission_changed (GPermission *permission,
                 gtk_widget_hide (get_widget (d, "user-icon-image"));
 
                 um_editable_button_set_editable (UM_EDITABLE_BUTTON (get_widget (d, 
"account-language-button")), TRUE);
-                remove_unlock_tooltip (get_widget (d, "account-language-button"));
-
                 um_editable_button_set_editable (UM_EDITABLE_BUTTON (get_widget (d, 
"account-password-button")), TRUE);
-                remove_unlock_tooltip (get_widget (d, "account-password-button"));
-
                 um_editable_button_set_editable (UM_EDITABLE_BUTTON (get_widget (d, 
"account-fingerprint-button")), TRUE);
-                remove_unlock_tooltip (get_widget (d, "account-fingerprint-button"));
         }
         else {
                 gtk_widget_hide (get_widget (d, "user-icon-button"));
                 gtk_widget_show (get_widget (d, "user-icon-image"));
 
                 um_editable_button_set_editable (UM_EDITABLE_BUTTON (get_widget (d, 
"account-language-button")), FALSE);
-                add_unlock_tooltip (get_widget (d, "account-language-button"));
-
                 um_editable_button_set_editable (UM_EDITABLE_BUTTON (get_widget (d, 
"account-password-button")), FALSE);
-                add_unlock_tooltip (get_widget (d, "account-password-button"));
-
                 um_editable_button_set_editable (UM_EDITABLE_BUTTON (get_widget (d, 
"account-fingerprint-button")), FALSE);
-                add_unlock_tooltip (get_widget (d, "account-fingerprint-button"));
         }
 
         um_password_dialog_set_user (d->password_dialog, user);
@@ -1475,70 +1130,6 @@ on_permission_changed (GPermission *permission,
         g_object_unref (user);
 }
 
-static gboolean
-match_user (GtkTreeModel *model,
-            gint          column,
-            const gchar  *key,
-            GtkTreeIter  *iter,
-            gpointer      search_data)
-{
-        ActUser *user;
-        const gchar *name;
-        gchar *normalized_key = NULL;
-        gchar *normalized_name = NULL;
-        gchar *case_normalized_key = NULL;
-        gchar *case_normalized_name = NULL;
-        gchar *p;
-        gboolean result = TRUE;
-        gint i;
-
-        gtk_tree_model_get (model, iter, USER_COL, &user, -1);
-
-        if (!user) {
-                goto out;
-        }
-
-        normalized_key = g_utf8_normalize (key, -1, G_NORMALIZE_ALL);
-        if (!normalized_key) {
-                goto out;
-        }
-
-        case_normalized_key = g_utf8_casefold (normalized_key, -1);
-
-        for (i = 0; i < 2; i++) {
-                if (i == 0) {
-                        name = act_user_get_real_name (user);
-                }
-                else {
-                        name = act_user_get_user_name (user);
-                }
-                g_free (normalized_name);
-                normalized_name = g_utf8_normalize (name, -1, G_NORMALIZE_ALL);
-                if (normalized_name) {
-                        g_free (case_normalized_name);
-                        case_normalized_name = g_utf8_casefold (normalized_name, -1);
-                        p = strstr (case_normalized_name, case_normalized_key);
-
-                        /* poor man's \b */
-                        if (p == case_normalized_name || (p && p[-1] == ' ')) {
-                                result = FALSE;
-                                break;
-                        }
-                }
-        }
-
- out:
-        if (user) {
-                g_object_unref (user);
-        }
-        g_free (normalized_key);
-        g_free (case_normalized_key);
-        g_free (normalized_name);
-        g_free (case_normalized_name);
-
-        return result;
-}
-
 static void
 update_padding (GtkWidget *button, GtkWidget *label)
 {
@@ -1563,86 +1154,11 @@ static void
 setup_main_window (CcUserPanel *self)
 {
         CcUserPanelPrivate *d = self->priv;
-        GtkWidget *userlist;
-        GtkTreeModel *model;
-        GtkListStore *store;
-        GtkTreeViewColumn *column;
-        GtkCellRenderer *cell;
-        GtkTreeSelection *selection;
         GtkWidget *button;
-        GtkTreeIter iter;
-        gint expander_size;
-        gchar *title;
-        GIcon *icon;
         GError *error = NULL;
-        gchar *names[3];
         gboolean loaded;
 
-        userlist = get_widget (d, "list-treeview");
-        store = gtk_list_store_new (NUM_USER_LIST_COLS,
-                                    ACT_TYPE_USER,
-                                    G_TYPE_STRING,
-                                    G_TYPE_BOOLEAN,
-                                    G_TYPE_STRING,
-                                    G_TYPE_BOOLEAN,
-                                    G_TYPE_INT);
-        model = (GtkTreeModel *)store;
-        gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (model), sort_users, NULL, NULL);
-        gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), 
GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
-        gtk_tree_view_set_model (GTK_TREE_VIEW (userlist), model);
-        gtk_tree_view_set_search_column (GTK_TREE_VIEW (userlist), USER_COL);
-        gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (userlist),
-                                             match_user, NULL, NULL);
-        g_object_unref (model);
-
-        gtk_widget_style_get (userlist, "expander-size", &expander_size, NULL);
-        gtk_tree_view_set_level_indentation (GTK_TREE_VIEW (userlist), - (expander_size + 6));
-
-        title = g_strdup_printf ("<small><span foreground=\"#555555\">%s</span></small>", _("My Account"));
-        gtk_list_store_append (store, &iter);
-        gtk_list_store_set (store, &iter,
-                            TITLE_COL, title,
-                            HEADING_ROW_COL, TRUE,
-                            SORT_KEY_COL, 0,
-                            -1);
-        g_free (title);
-
-        d->other_accounts = 0;
-        d->other_iter = NULL;
-
-        column = gtk_tree_view_column_new ();
-        cell = um_cell_renderer_user_image_new (userlist);
-        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), cell, FALSE);
-        gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (column), cell, "user", USER_COL);
-        gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (column), cell, "visible", USER_ROW_COL);
-        cell = gtk_cell_renderer_text_new ();
-        g_object_set (cell, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
-        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), cell, TRUE);
-        gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (column), cell, "markup", NAME_COL);
-        gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (column), cell, "visible", USER_ROW_COL);
-        cell = gtk_cell_renderer_text_new ();
-        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), cell, TRUE);
-        gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (column), cell, "markup", TITLE_COL);
-        gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (column), cell, "visible", HEADING_ROW_COL);
-
-        gtk_tree_view_append_column (GTK_TREE_VIEW (userlist), column);
-
-        selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (userlist));
-        gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
-        g_signal_connect (selection, "changed", G_CALLBACK (selected_user_changed), d);
-        gtk_tree_selection_set_select_function (selection, dont_select_headings, NULL, NULL);
-
-        gtk_scrolled_window_set_min_content_width (GTK_SCROLLED_WINDOW (get_widget (d, 
"list-scrolledwindow")), 300);
-        gtk_widget_set_size_request (get_widget (d, "list-scrolledwindow"), 200, -1);
-
-        button = get_widget (d, "add-user-toolbutton");
-        g_signal_connect (button, "clicked", G_CALLBACK (add_user), d);
-
-        button = get_widget (d, "remove-user-toolbutton");
-        g_signal_connect (button, "clicked", G_CALLBACK (delete_user), self);
-
         button = get_widget (d, "user-icon-image");
-        add_unlock_tooltip (button);
 
         button = get_widget (d, "full-name-entry");
         g_signal_connect (button, "editing-done", G_CALLBACK (change_name_done), d);
@@ -1678,22 +1194,6 @@ setup_main_window (CcUserPanel *self)
                 g_error_free (error);
         }
 
-        button = get_widget (d, "add-user-toolbutton");
-        names[0] = "changes-allow-symbolic";
-        names[1] = "changes-allow";
-        names[2] = NULL;
-        icon = (GIcon *)g_themed_icon_new_from_names (names, -1);
-        setup_tooltip_with_embedded_icon (button,
-                                          _("To create a user account,\nclick the * icon first"),
-                                          "*",
-                                          icon);
-        button = get_widget (d, "remove-user-toolbutton");
-        setup_tooltip_with_embedded_icon (button,
-                                          _("To delete the selected user account,\nclick the * icon first"),
-                                          "*",
-                                          icon);
-        g_object_unref (icon);
-
         g_object_get (d->um, "is-loaded", &loaded, NULL);
         if (loaded)
                 users_loaded (d->um, NULL, d);
@@ -1731,7 +1231,6 @@ cc_user_panel_init (CcUserPanel *self)
         GError *error;
         volatile GType type G_GNUC_UNUSED;
         GtkWidget *button;
-        GtkStyleContext *context;
 
         d = self->priv = UM_USER_PANEL_PRIVATE (self);
         g_resources_register (um_get_resource ());
@@ -1742,6 +1241,7 @@ cc_user_panel_init (CcUserPanel *self)
         type = um_editable_combo_get_type ();
         type = um_user_image_get_type ();
         type = um_cell_renderer_user_image_get_type ();
+        type = um_carousel_get_type ();
 
         gtk_widget_set_size_request (GTK_WIDGET (self), -1, 350);
 
@@ -1766,12 +1266,15 @@ cc_user_panel_init (CcUserPanel *self)
         d->main_box = get_widget (d, "accounts-vbox");
         gtk_container_add (GTK_CONTAINER (self), get_widget (d, "overlay"));
         d->history_dialog = um_history_dialog_new ();
-        setup_main_window (self);
 
-        context = gtk_widget_get_style_context (get_widget (d, "list-scrolledwindow"));
-        gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
-        context = gtk_widget_get_style_context (get_widget (d, "add-remove-toolbar"));
-        gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
+        d->carousel = UM_CAROUSEL (get_widget (d, "carousel"));
+        g_signal_connect (d->carousel, "item-activated", G_CALLBACK (item_toggled), d);
+        d->selected_user = NULL;
+        d->users_list = g_list_store_new (act_user_get_type ());
+        um_carousel_bind_model (d->carousel, G_LIST_MODEL (d->users_list),
+                                create_user_item, NULL, NULL);
+
+        setup_main_window (self);
 }
 
 static void
@@ -1816,10 +1319,6 @@ cc_user_panel_dispose (GObject *object)
                 g_object_unref (priv->permission);
                 priv->permission = NULL;
         }
-        if (priv->other_iter) {
-                gtk_tree_iter_free (priv->other_iter);
-                priv->other_iter = NULL;
-        }
         G_OBJECT_CLASS (cc_user_panel_parent_class)->dispose (object);
 }
 
diff --git a/panels/user-accounts/user-accounts.gresource.xml 
b/panels/user-accounts/user-accounts.gresource.xml
index ad57a8a..4bedc2d 100644
--- a/panels/user-accounts/user-accounts.gresource.xml
+++ b/panels/user-accounts/user-accounts.gresource.xml
@@ -7,6 +7,7 @@
     <file alias="password-dialog.ui" preprocess="xml-stripblanks">data/password-dialog.ui</file>
     <file alias="history-dialog.ui" preprocess="xml-stripblanks">data/history-dialog.ui</file>
     <file alias="user-accounts-dialog.ui" preprocess="xml-stripblanks">data/user-accounts-dialog.ui</file>
+    <file alias="carousel.ui" preprocess="xml-stripblanks">data/carousel.ui</file>
     <file alias="left-index-finger.png">data/icons/left-index-finger.png</file>
     <file alias="left-middle-finger.png">data/icons/left-middle-finger.png</file>
     <file alias="left-little-finger.png">data/icons/left-little-finger.png</file>


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