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



commit a50ac2fafad6bb668d60a50dd4450b056233f505
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
    
    Upstream status: This patch needs to be cleaned up significantly before
    it can go upstream. We don't want any of the unrelated changes. There's
    no value in syncing this file with nautilus because they're going to
    delete theirs.
    
    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]