[epiphany/wip/mcatanzaro/fedora-needs-upstreamed: 12/20] nautilus-floating-bar: hide on hover



commit 434db34d2e8bab5243e215f76cfdb588a20ef6a3
Author: Michael Catanzaro <mcatanzaro igalia com>
Date:   Thu Feb 26 14:05:28 2015 -0600

    nautilus-floating-bar: hide on hover
    
    Hide on hover work is by Nelson Benitez
    
    The update also includes some style tweaks from Cosimo.
    
    A couple ephy-specific changes are tagged EPIPHANY
    
    https://bugzilla.gnome.org/show_bug.cgi?id=651293
    https://bugzilla.gnome.org/show_bug.cgi?id=742590

 embed/ephy-embed.c                  |    4 +-
 lib/widgets/nautilus-floating-bar.c |  263 +++++++++++++++++++++++++++++-----
 lib/widgets/nautilus-floating-bar.h |   11 +-
 3 files changed, 233 insertions(+), 45 deletions(-)
---
diff --git a/embed/ephy-embed.c b/embed/ephy-embed.c
index 798bbc4..f1f3227 100644
--- a/embed/ephy-embed.c
+++ b/embed/ephy-embed.c
@@ -716,8 +716,8 @@ ephy_embed_constructed (GObject *object)
   gtk_overlay_add_overlay (GTK_OVERLAY (overlay), priv->fullscreen_message_label);
   ephy_embed_set_fullscreen_message (embed, FALSE);
 
-  /* statusbar is hidden by default */
-  priv->floating_bar = nautilus_floating_bar_new (NULL, NULL, FALSE);
+  /* statusbar is hidden by default, hide on hover is on */
+  priv->floating_bar = nautilus_floating_bar_new (NULL, NULL, FALSE, TRUE);
   gtk_widget_set_halign (priv->floating_bar, GTK_ALIGN_START);
   gtk_widget_set_valign (priv->floating_bar, GTK_ALIGN_END);
   gtk_widget_set_no_show_all (priv->floating_bar, TRUE);
diff --git a/lib/widgets/nautilus-floating-bar.c b/lib/widgets/nautilus-floating-bar.c
index 0eff290..8d789c2 100644
--- a/lib/widgets/nautilus-floating-bar.c
+++ b/lib/widgets/nautilus-floating-bar.c
@@ -15,9 +15,7 @@
  * Library General Public License for more details.
  *
  * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  *
  * Authors: Cosimo Cecchi <cosimoc redhat com>
  *
@@ -29,6 +27,8 @@
 
 #include "nautilus-floating-bar.h"
 
+#define HOVER_HIDE_TIMEOUT_INTERVAL 250
+
 struct _NautilusFloatingBarDetails {
        gchar *primary_label;
        gchar *details_label;
@@ -38,12 +38,15 @@ struct _NautilusFloatingBarDetails {
        GtkWidget *spinner;
        gboolean show_spinner;
        gboolean is_interactive;
+       gboolean hover_hide;
+       guint hover_timeout_id;
 };
 
 enum {
        PROP_PRIMARY_LABEL = 1,
        PROP_DETAILS_LABEL,
        PROP_SHOW_SPINNER,
+       PROP_HOVER_HIDE,
        NUM_PROPERTIES
 };
 
@@ -99,6 +102,9 @@ nautilus_floating_bar_get_property (GObject *object,
        case PROP_SHOW_SPINNER:
                g_value_set_boolean (value, self->priv->show_spinner);
                break;
+       case PROP_HOVER_HIDE:
+               g_value_set_boolean (value, self->priv->hover_hide);
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
                break;
@@ -123,6 +129,9 @@ nautilus_floating_bar_set_property (GObject *object,
        case PROP_SHOW_SPINNER:
                nautilus_floating_bar_set_show_spinner (self, g_value_get_boolean (value));
                break;
+       case PROP_HOVER_HIDE:
+               self->priv->hover_hide = g_value_get_boolean (value);
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
                break;
@@ -148,30 +157,140 @@ update_labels (NautilusFloatingBar *self)
        gtk_widget_set_visible (self->priv->details_label_widget, details_visible);
 }
 
+static void
+nautilus_floating_bar_show (GtkWidget *widget)
+{
+       NautilusFloatingBar *self = NAUTILUS_FLOATING_BAR (widget);
+
+       // EPIPHANY: don't want to unhide the widget if it's going to appear on the top of the screen
+       if (gtk_widget_get_valign (widget) == GTK_ALIGN_START)
+               return;
+
+       GTK_WIDGET_CLASS (nautilus_floating_bar_parent_class)->show (widget);
+
+       if (self->priv->show_spinner) {
+               gtk_spinner_start (GTK_SPINNER (self->priv->spinner));
+       }
+}
+
+static void
+nautilus_floating_bar_hide (GtkWidget *widget)
+{
+       NautilusFloatingBar *self = NAUTILUS_FLOATING_BAR (widget);
+
+       GTK_WIDGET_CLASS (nautilus_floating_bar_parent_class)->hide (widget);
+
+       gtk_spinner_stop (GTK_SPINNER (self->priv->spinner));
+}
+
+void
+nautilus_floating_bar_remove_hover_timeout (NautilusFloatingBar *self)
+{
+       if (self->priv->hover_timeout_id != 0) {
+               g_source_remove (self->priv->hover_timeout_id);
+               self->priv->hover_timeout_id = 0;
+       }
+}
+
+typedef struct {
+       GtkWidget *overlay;
+       GtkWidget *floating_bar;
+       GdkDevice *device;
+       gint y_down_limit;
+       gint y_upper_limit;
+       gboolean first_time;
+} CheckPointerData;
+
+static void
+check_pointer_data_free (gpointer data)
+{
+       g_slice_free (CheckPointerData, data);
+}
+
+static gboolean
+check_pointer_timeout (gpointer user_data)
+{
+  CheckPointerData *data = user_data;
+  gint pointer_y = -1;
+
+  gdk_window_get_device_position (gtk_widget_get_window (data->overlay), data->device,
+                                  NULL, &pointer_y, NULL);
+
+  if (pointer_y == -1 || pointer_y < data->y_down_limit || pointer_y > data->y_upper_limit) {
+       if (! data->first_time) {
+               gtk_widget_set_valign (data->floating_bar, GTK_ALIGN_END);
+               nautilus_floating_bar_show (data->floating_bar);
+       }
+       NAUTILUS_FLOATING_BAR (data->floating_bar)->priv->hover_timeout_id = 0;
+
+       return G_SOURCE_REMOVE;
+
+  } else if (data->first_time) {
+       //hide floating bar at top position of widget
+       nautilus_floating_bar_hide (data->floating_bar);
+       gtk_widget_set_valign (data->floating_bar, GTK_ALIGN_START);
+       gtk_widget_queue_resize (data->floating_bar);
+  }
+
+  if (data->first_time) {
+       data->first_time = FALSE;
+  }
+
+  return G_SOURCE_CONTINUE;
+}
+
 static gboolean
 overlay_enter_notify_cb (GtkWidget        *parent,
                         GdkEventCrossing *event,
                         gpointer          user_data)
 {
        GtkWidget *widget = user_data;
+       CheckPointerData *data;
+       GtkAllocation alloc_parent;
+       gint y_pos;
+
+       NautilusFloatingBar *self = NAUTILUS_FLOATING_BAR (widget);
+
+       if (self->priv->hover_timeout_id != 0) {
+               g_source_remove (self->priv->hover_timeout_id);
+       }
 
        if (event->window != gtk_widget_get_window (widget)) {
-               return FALSE;
+               return GDK_EVENT_PROPAGATE;
        }
 
        if (NAUTILUS_FLOATING_BAR (widget)->priv->is_interactive) {
-               return FALSE;
+               return GDK_EVENT_PROPAGATE;
        }
 
-       if (gtk_widget_get_halign (widget) == GTK_ALIGN_START) {
-               gtk_widget_set_halign (widget, GTK_ALIGN_END);
-       } else {
-               gtk_widget_set_halign (widget, GTK_ALIGN_START);
+       if (! self->priv->hover_hide) {
+               if (gtk_widget_get_halign (widget) == GTK_ALIGN_START) {
+                       gtk_widget_set_halign (widget, GTK_ALIGN_END);
+               } else {
+                       gtk_widget_set_halign (widget, GTK_ALIGN_START);
+               }
+
+               return GDK_EVENT_PROPAGATE;
        }
 
-       gtk_widget_queue_resize (widget);
+       gtk_widget_get_allocation (parent, &alloc_parent);
+       gdk_window_get_position (gtk_widget_get_window (widget), NULL, &y_pos);
 
-       return FALSE;
+       data = g_slice_new (CheckPointerData);
+       data->overlay = parent;
+       data->floating_bar = widget;
+       data->device = gdk_event_get_device ((GdkEvent *) event);
+       data->y_down_limit = y_pos;
+       data->y_upper_limit = alloc_parent.height;
+       data->first_time = TRUE;
+
+       self->priv->hover_timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT, HOVER_HIDE_TIMEOUT_INTERVAL,
+                                                               check_pointer_timeout, data,
+                                                               check_pointer_data_free);
+
+       g_source_set_name_by_id (self->priv->hover_timeout_id, "[nautilus-floating-bar] 
overlay_enter_notify_cb");
+
+       return GDK_EVENT_STOP;
 }
 
 static void
@@ -194,49 +313,94 @@ nautilus_floating_bar_parent_set (GtkWidget *widget,
 }
 
 static void
-nautilus_floating_bar_show (GtkWidget *widget)
+get_padding_and_border (GtkWidget *widget,
+                        GtkBorder *border)
 {
-       NautilusFloatingBar *self = NAUTILUS_FLOATING_BAR (widget);
+  GtkStyleContext *context;
+  GtkStateFlags state;
+  GtkBorder tmp;
+
+  context = gtk_widget_get_style_context (widget);
+  state = gtk_widget_get_state_flags (widget);
+
+  gtk_style_context_get_padding (context, state, border);
+  gtk_style_context_get_border (context, state, &tmp);
+  border->top += tmp.top;
+  border->right += tmp.right;
+  border->bottom += tmp.bottom;
+  border->left += tmp.left;
+}
 
-       GTK_WIDGET_CLASS (nautilus_floating_bar_parent_class)->show (widget);
+static void
+nautilus_floating_bar_get_preferred_width (GtkWidget *widget,
+                                          gint      *minimum_size,
+                                          gint      *natural_size)
+{
+       GtkBorder border;
 
-       if (self->priv->show_spinner) {
-               gtk_spinner_start (GTK_SPINNER (self->priv->spinner));
-       }
+       get_padding_and_border (widget, &border);
+
+       GTK_WIDGET_CLASS (nautilus_floating_bar_parent_class)->get_preferred_width (widget,
+                                                                                   minimum_size,
+                                                                                   natural_size);
+
+       *minimum_size += border.left + border.right;
+       *natural_size += border.left + border.right;
 }
 
 static void
-nautilus_floating_bar_hide (GtkWidget *widget)
+nautilus_floating_bar_get_preferred_width_for_height (GtkWidget *widget,
+                                                     gint       height,
+                                                     gint      *minimum_size,
+                                                     gint      *natural_size)
 {
-       NautilusFloatingBar *self = NAUTILUS_FLOATING_BAR (widget);
+       GtkBorder border;
 
-       GTK_WIDGET_CLASS (nautilus_floating_bar_parent_class)->hide (widget);
+       get_padding_and_border (widget, &border);
 
-       gtk_spinner_stop (GTK_SPINNER (self->priv->spinner));
+       GTK_WIDGET_CLASS (nautilus_floating_bar_parent_class)->get_preferred_width_for_height (widget,
+                                                                                              height,
+                                                                                              minimum_size,
+                                                                                              natural_size);
+
+       *minimum_size += border.left + border.right;
+       *natural_size += border.left + border.right;
 }
 
-static gboolean
-nautilus_floating_bar_draw (GtkWidget *widget,
-                           cairo_t *cr)
+static void
+nautilus_floating_bar_get_preferred_height (GtkWidget *widget,
+                                           gint      *minimum_size,
+                                           gint      *natural_size)
 {
-       GtkStyleContext *context;
+       GtkBorder border;
 
-       context = gtk_widget_get_style_context (widget);
+       get_padding_and_border (widget, &border);
 
-       gtk_style_context_save (context);
-       gtk_style_context_set_state (context, gtk_widget_get_state_flags (widget));
+       GTK_WIDGET_CLASS (nautilus_floating_bar_parent_class)->get_preferred_height (widget,
+                                                                                    minimum_size,
+                                                                                    natural_size);
 
-       gtk_render_background (context, cr, 0, 0,
-                              gtk_widget_get_allocated_width (widget),
-                              gtk_widget_get_allocated_height (widget));
+       *minimum_size += border.top + border.bottom;
+       *natural_size += border.top + border.bottom;
+}
+
+static void
+nautilus_floating_bar_get_preferred_height_for_width (GtkWidget *widget,
+                                                     gint       width,
+                                                     gint      *minimum_size,
+                                                     gint      *natural_size)
+{
+       GtkBorder border;
 
-       gtk_render_frame (context, cr, 0, 0,
-                         gtk_widget_get_allocated_width (widget),
-                         gtk_widget_get_allocated_height (widget));
+       get_padding_and_border (widget, &border);
 
-       gtk_style_context_restore (context);
+       GTK_WIDGET_CLASS (nautilus_floating_bar_parent_class)->get_preferred_height_for_width (widget,
+                                                                                              width,
+                                                                                              minimum_size,
+                                                                                              natural_size);
 
-       return GTK_WIDGET_CLASS (nautilus_floating_bar_parent_class)->draw (widget, cr);;
+       *minimum_size += border.top + border.bottom;
+       *natural_size += border.top + border.bottom;
 }
 
 static void
@@ -255,7 +419,7 @@ nautilus_floating_bar_constructed (GObject *obj)
        self->priv->spinner = w;
 
        gtk_widget_set_size_request (w, 16, 16);
-       gtk_widget_set_margin_left (w, 8);
+       gtk_widget_set_margin_start (w, 8);
 
        labels_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
        gtk_box_pack_start (GTK_BOX (box), labels_box, TRUE, TRUE, 0);
@@ -304,7 +468,10 @@ nautilus_floating_bar_class_init (NautilusFloatingBarClass *klass)
        oclass->get_property = nautilus_floating_bar_get_property;
        oclass->finalize = nautilus_floating_bar_finalize;
 
-       wclass->draw = nautilus_floating_bar_draw;
+       wclass->get_preferred_width = nautilus_floating_bar_get_preferred_width;
+       wclass->get_preferred_width_for_height = nautilus_floating_bar_get_preferred_width_for_height;
+       wclass->get_preferred_height = nautilus_floating_bar_get_preferred_height;
+       wclass->get_preferred_height_for_width = nautilus_floating_bar_get_preferred_height_for_width;
        wclass->show = nautilus_floating_bar_show;
        wclass->hide = nautilus_floating_bar_hide;
        wclass->parent_set = nautilus_floating_bar_parent_set;
@@ -328,6 +495,14 @@ nautilus_floating_bar_class_init (NautilusFloatingBarClass *klass)
                                      FALSE,
                                      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 
+       properties[PROP_HOVER_HIDE] =
+               g_param_spec_boolean ("hover-hide",
+                                     "Hide bar on hover",
+                                     "Whether the floating bar should be hidden on hover",
+                                     TRUE,
+                                     G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
+                                     G_PARAM_STATIC_STRINGS);
+
        signals[ACTION] =
                g_signal_new ("action",
                              G_TYPE_FROM_CLASS (klass),
@@ -347,6 +522,7 @@ nautilus_floating_bar_set_primary_label (NautilusFloatingBar *self,
 {
        if (g_strcmp0 (self->priv->primary_label, label) != 0) {
                g_free (self->priv->primary_label);
+               // EPIPHANY: The URI is stored escaped
                self->priv->primary_label = g_uri_unescape_string (label, NULL);
 
                g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PRIMARY_LABEL]);
@@ -391,15 +567,23 @@ nautilus_floating_bar_set_show_spinner (NautilusFloatingBar *self,
        }
 }
 
+gboolean
+nautilus_floating_bar_is_hover_hide (NautilusFloatingBar *self)
+{
+       return self->priv->hover_hide;
+}
+
 GtkWidget *
 nautilus_floating_bar_new (const gchar *primary_label,
                           const gchar *details_label,
-                          gboolean show_spinner)
+                          gboolean show_spinner,
+                          gboolean hover_hide)
 {
        return g_object_new (NAUTILUS_TYPE_FLOATING_BAR,
                             "primary-label", primary_label,
                             "details-label", details_label,
                             "show-spinner", show_spinner,
+                            "hover-hide", hover_hide,
                             "orientation", GTK_ORIENTATION_HORIZONTAL,
                             "spacing", 8,
                             NULL);
@@ -416,6 +600,7 @@ nautilus_floating_bar_add_action (NautilusFloatingBar *self,
        gtk_widget_show (w);
 
        button = gtk_button_new ();
+       gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
        gtk_button_set_image (GTK_BUTTON (button), w);
        gtk_box_pack_end (GTK_BOX (self), button, FALSE, FALSE, 0);
        gtk_widget_show (button);
diff --git a/lib/widgets/nautilus-floating-bar.h b/lib/widgets/nautilus-floating-bar.h
index ba31ac5..44ab659 100644
--- a/lib/widgets/nautilus-floating-bar.h
+++ b/lib/widgets/nautilus-floating-bar.h
@@ -15,9 +15,7 @@
  * Library General Public License for more details.
  *
  * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  *
  * Authors: Cosimo Cecchi <cosimoc redhat com>
  *
@@ -60,7 +58,8 @@ GType       nautilus_floating_bar_get_type  (void);
 
 GtkWidget * nautilus_floating_bar_new              (const gchar *primary_label,
                                                    const gchar *details_label,
-                                                   gboolean show_spinner);
+                                                   gboolean show_spinner,
+                                                   gboolean hover_hide);
 
 void       nautilus_floating_bar_set_primary_label (NautilusFloatingBar *self,
                                                    const gchar *label);
@@ -77,5 +76,9 @@ void        nautilus_floating_bar_add_action       (NautilusFloatingBar *self,
                                                    gint action_id);
 void        nautilus_floating_bar_cleanup_actions  (NautilusFloatingBar *self);
 
+void        nautilus_floating_bar_remove_hover_timeout (NautilusFloatingBar *self);
+
+gboolean    nautilus_floating_bar_is_hover_hide (NautilusFloatingBar *self);
+
 #endif /* __NAUTILUS_FLOATING_BAR_H__ */
 


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