[gnome-control-center/wip/feborges/new-users-panel: 5/7] user-accounts: Draw arrow in UmCarousel



commit 3dc957e96222a10cb1a06fa702aeb4b441c4067d
Author: Felipe Borges <felipeborges gnome org>
Date:   Sat Dec 10 22:48:11 2016 +0100

    user-accounts: Draw arrow in UmCarousel
    
    The arrow is drawn using CSS.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=767065

 panels/user-accounts/data/carousel.css           |   14 ++++
 panels/user-accounts/data/carousel.ui            |   28 +++++++-
 panels/user-accounts/um-carousel.c               |   83 ++++++++++++++++++----
 panels/user-accounts/user-accounts.gresource.xml |    1 +
 4 files changed, 110 insertions(+), 16 deletions(-)
---
diff --git a/panels/user-accounts/data/carousel.css b/panels/user-accounts/data/carousel.css
new file mode 100644
index 0000000..a6b7205
--- /dev/null
+++ b/panels/user-accounts/data/carousel.css
@@ -0,0 +1,14 @@
+.arrow {
+  background: linear-gradient(45deg, transparent 50%, #D9D9D7 50%),
+              linear-gradient(-45deg, transparent 50%, #D9D9D7 50%),
+              linear-gradient(to bottom, @borders, @borders);
+  padding: 1px;
+  margin: -3px;
+}
+
+.inner-arrow {
+  border-left: 26px solid transparent;
+  border-right: 26px solid transparent;
+  border-bottom: 26px solid @theme_bg_color;
+  margin-bottom: -8px;
+}
diff --git a/panels/user-accounts/data/carousel.ui b/panels/user-accounts/data/carousel.ui
index ab49bdc..4f3d480 100644
--- a/panels/user-accounts/data/carousel.ui
+++ b/panels/user-accounts/data/carousel.ui
@@ -2,6 +2,7 @@
 <interface>
   <!-- interface-requires gtk+ 3.8 -->
   <template class="UmCarousel" parent="GtkBox">
+    <property name="orientation">GTK_ORIENTATION_VERTICAL</property>
     <style>
       <class name="location-bar"/>
     </style>
@@ -9,11 +10,12 @@
       <object class="GtkOverlay">
         <property name="visible">True</property>
         <property name="hexpand">True</property>
-        <property name="border_width">30</property>
+        <property name="valign">GTK_ALIGN_START</property>
+        <property name="margin-top">36</property>
         <child>
           <object class="GtkStack" id="stack">
             <property name="visible">True</property>
-            <property name="valign">GTK_ALIGN_CENTER</property>
+            <property name="valign">GTK_ALIGN_START</property>
             <property name="transition_type">GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT</property>
             <property name="transition_duration">400</property>
           </object>
@@ -23,6 +25,7 @@
             <property name="visible">True</property>
             <property name="orientation">horizontal</property>
             <property name="border_width">12</property>
+            <property name="valign">GTK_ALIGN_START</property>
             <child>
               <object class="GtkButton" id="go_back_button">
                 <property name="visible">False</property>
@@ -73,5 +76,26 @@
         </child>
       </object>
     </child>
+    <child>
+      <object class="GtkBox" id="arrow">
+        <property name="visible">True</property>
+        <property name="height-request">36</property>
+        <property name="width-request">36</property>
+        <property name="halign">GTK_ALIGN_START</property>
+        <style>
+          <class name="arrow"/>
+        </style>
+        <child>
+          <object class="GtkBox">
+            <property name="visible">True</property>
+            <property name="height-request">34</property>
+            <property name="width-request">34</property>
+            <style>
+              <class name="inner-arrow"/>
+            </style>
+          </object>
+        </child>
+      </object>
+    </child>
   </template>
 </interface>
diff --git a/panels/user-accounts/um-carousel.c b/panels/user-accounts/um-carousel.c
index fe8df2f..3260f44 100644
--- a/panels/user-accounts/um-carousel.c
+++ b/panels/user-accounts/um-carousel.c
@@ -23,6 +23,8 @@
 #include <glib-object.h>
 #include <gtk/gtk.h>
 
+#define ARROW_WIDTH 28
+
 struct _UmCarouselItem {
         GtkToggleButton parent;
 
@@ -59,6 +61,7 @@ struct _UmCarousel {
         GtkStack *stack;
         GtkWidget *go_back_button;
         GtkWidget *go_next_button;
+        GtkWidget *arrow;
 };
 
 G_DEFINE_TYPE (UmCarousel, um_carousel, GTK_TYPE_BOX)
@@ -120,15 +123,50 @@ um_carousel_find_item (UmCarousel    *self,
         return NULL;
 }
 
+static void
+um_carousel_point_arrow_to_item (UmCarousel     *self,
+                                 UmCarouselItem *item)
+{
+        GtkAllocation alloc;
+        GtkWidget *carousel;
+        gint item_width;
+        gint dest_x;
+
+        carousel = GTK_WIDGET (self);
+
+        item_width = gtk_widget_get_allocated_width (GTK_WIDGET (item));
+        gtk_widget_translate_coordinates (GTK_WIDGET (item),
+                                          carousel,
+                                          item_width / 2,
+                                          0,
+                                          &dest_x,
+                                          NULL);
+
+        gtk_widget_get_allocation (self->arrow, &alloc);
+        alloc.x = CLAMP (dest_x - ARROW_WIDTH, 0, gtk_widget_get_allocated_width (carousel));
+        gtk_widget_size_allocate (self->arrow, &alloc);
+
+        gtk_widget_queue_draw (carousel);
+}
+
+static void
+on_item_toggled (UmCarouselItem *item,
+                 gpointer        user_data)
+{
+        UmCarousel *self = UM_CAROUSEL (user_data);
+
+        self->selected_item = item;
+
+        g_signal_emit (user_data, signals[ITEM_ACTIVATED], 0, item);
+}
+
 void
 um_carousel_select_item (UmCarousel     *self,
                          UmCarouselItem *item)
 {
         gchar *page_name;
 
-        self->selected_item = item;
-
-        g_signal_emit (self, signals[ITEM_ACTIVATED], 0, self->selected_item);
+        on_item_toggled (item, self);
 
         self->visible_page = item->page;
         page_name = g_strdup_printf ("%d", self->visible_page);
@@ -181,17 +219,6 @@ um_carousel_goto_next_page (GtkWidget *button,
 }
 
 static void
-on_item_toggled (UmCarouselItem *item,
-                 gpointer        user_data)
-{
-        UmCarousel *self = UM_CAROUSEL (user_data);
-
-        self->selected_item = item;
-
-        g_signal_emit (user_data, signals[ITEM_ACTIVATED], 0, item);
-}
-
-static void
 um_carousel_add (GtkContainer *container,
                  GtkWidget    *widget)
 {
@@ -237,6 +264,20 @@ um_carousel_purge_items (UmCarousel *self)
         self->visible_page = 0;
 }
 
+static gboolean
+um_carousel_draw (GtkWidget *widget,
+                  cairo_t   *cr)
+{
+  UmCarousel *self = UM_CAROUSEL (widget);
+
+  if (self->selected_item)
+          um_carousel_point_arrow_to_item (self, self->selected_item);
+
+  GTK_WIDGET_CLASS (um_carousel_parent_class)->draw (widget, cr);
+
+  return TRUE;
+}
+
 UmCarousel *
 um_carousel_new (void)
 {
@@ -255,11 +296,13 @@ um_carousel_class_init (UmCarouselClass *klass)
         gtk_widget_class_bind_template_child (wclass, UmCarousel, stack);
         gtk_widget_class_bind_template_child (wclass, UmCarousel, go_back_button);
         gtk_widget_class_bind_template_child (wclass, UmCarousel, go_next_button);
+        gtk_widget_class_bind_template_child (wclass, UmCarousel, arrow);
 
         gtk_widget_class_bind_template_callback (wclass, um_carousel_goto_previous_page);
         gtk_widget_class_bind_template_callback (wclass, um_carousel_goto_next_page);
 
         container_class->add = um_carousel_add;
+        wclass->draw = um_carousel_draw;
 
         signals[ITEM_ACTIVATED] = g_signal_new ("item-activated",
                                                 UM_TYPE_CAROUSEL,
@@ -274,5 +317,17 @@ um_carousel_class_init (UmCarouselClass *klass)
 static void
 um_carousel_init (UmCarousel *self)
 {
+        GtkStyleProvider *provider;
+
         gtk_widget_init_template (GTK_WIDGET (self));
+
+        provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
+        gtk_css_provider_load_from_resource (GTK_CSS_PROVIDER (provider),
+                                             "/org/gnome/control-center/user-accounts/carousel.css");
+
+        gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
+                                                   provider,
+                                                   GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+
+        g_object_unref (provider);
 }
diff --git a/panels/user-accounts/user-accounts.gresource.xml 
b/panels/user-accounts/user-accounts.gresource.xml
index 4bedc2d..fd960bc 100644
--- a/panels/user-accounts/user-accounts.gresource.xml
+++ b/panels/user-accounts/user-accounts.gresource.xml
@@ -8,6 +8,7 @@
     <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="carousel.css">data/carousel.css</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]