[nautilus/wip/minButWidth: 2/2] nautilus-pathbar: Allow label shrinking



commit 80754ac37ff677f1c7603e67b3e7a195f34f6299
Author: Carlos Soriano <carlos soriano89 gmail com>
Date:   Tue Sep 23 15:52:37 2014 +0200

    nautilus-pathbar: Allow label shrinking
    
    Currently the labels of the pathbar set a required size based on its
    preferred size. That brings the problem that setting a minimum size of
    its preferred size doesn't allow to shrink the label when needed, e.g.
    when the windows need to be snapped to a side or when making the window
    smaller.
    To avoid that, implement a GObject that its preferred size its natural
    size, and minimum size of 0, allowing the label to shrink when necesary.

 src/Makefile.am                     |    2 +
 src/nautilus-pathbar-button-label.c |  168 +++++++++++++++++++++++++++++++++++
 src/nautilus-pathbar-button-label.h |   65 ++++++++++++++
 src/nautilus-pathbar.c              |   76 +++-------------
 4 files changed, 249 insertions(+), 62 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 2aaea24..424abb0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -185,6 +185,8 @@ nautilus_SOURCES = \
        nautilus-mime-actions.h                 \
        nautilus-notebook.c                     \
        nautilus-notebook.h                     \
+       nautilus-pathbar-button-label.h         \
+       nautilus-pathbar-button-label.c         \
        nautilus-pathbar.c                      \
        nautilus-pathbar.h                      \
        nautilus-previewer.c                    \
diff --git a/src/nautilus-pathbar-button-label.c b/src/nautilus-pathbar-button-label.c
new file mode 100644
index 0000000..dab83dc
--- /dev/null
+++ b/src/nautilus-pathbar-button-label.c
@@ -0,0 +1,168 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* nautilus-pathbar-button-label.c
+ *
+ * Copyright (C) 2014  Carlos Soriano <carlos soriano89 gmail com>
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors Carlos Soriano <carlos soriano89 gmail com>
+ */
+
+/*
+ * GObject that provide the same requested size for default and bold
+ * label markup.
+ */
+
+#include "nautilus-pathbar-button-label.h"
+#include "nautilus-pathbar.h"
+
+#define NAUTILUS_PATH_BAR_LABEL_MAX_WIDTH 250
+#define NAUTILUS_PATH_BAR_LABEL_MIN_WIDTH 50
+
+struct _NautilusPathbarButtonLabelPrivate
+{
+       GtkLabel *label;
+       GtkLabel *bold_label;
+       gchar    *dir_name;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (NautilusPathbarButtonLabel, nautilus_pathbar_button_label, GTK_TYPE_BOX)
+
+NautilusPathbarButtonLabel *
+nautilus_pathbar_button_label_new (void)
+{
+       return g_object_new (NAUTILUS_TYPE_PATHBAR_BUTTON_LABEL, NULL);
+}
+
+static void
+nautilus_pathbar_button_label_finalize (GObject *object)
+{
+       NautilusPathbarButtonLabelPrivate *priv = NAUTILUS_PATHBAR_BUTTON_LABEL (object)->priv;
+
+       G_OBJECT_CLASS (nautilus_pathbar_button_label_parent_class)->finalize (object);
+
+       //g_object_unref(priv->label);
+       //g_object_unref(priv->bold_label);
+
+       g_free(priv->dir_name);
+}
+
+void
+nautilus_pathbar_button_label_set_text(NautilusPathbarButtonLabel *self,
+                                      gchar *dir_name)
+{
+       g_free(self->priv->dir_name);
+       self->priv->dir_name = g_strdup(dir_name);
+
+       char *markup = g_markup_printf_escaped ("<b>%s</b>", dir_name);
+
+       if (gtk_label_get_use_markup (self->priv->label)) {
+               gtk_label_set_markup (self->priv->label, markup);
+       } else {
+               gtk_label_set_text (self->priv->label, dir_name);
+       }
+
+       gtk_label_set_markup (self->priv->bold_label, markup);
+       g_free (markup);
+}
+
+void
+nautilus_pathbar_button_label_set_bold(NautilusPathbarButtonLabel *self,
+                                      gboolean *bold)
+{
+       if (bold) {
+               if (self->priv->dir_name) {
+                       char *markup;
+                       markup = g_markup_printf_escaped ("<b>%s</b>", self->priv->dir_name);
+                       gtk_label_set_markup (self->priv->label, markup);
+                       g_free (markup);
+               }
+
+               gtk_label_set_use_markup (self->priv->label, TRUE);
+
+       } else {
+               gtk_label_set_use_markup (self->priv->label, FALSE);
+               if (self->priv->dir_name) {
+                       gtk_label_set_text(self->priv->label, self->priv->dir_name);
+               }
+       }
+}
+
+static void
+nautilus_pathbar_button_label_get_preferred_width (GtkWidget *widget,
+                                                  gint      *minimum,
+                                                  gint      *natural)
+{
+       int width;
+       GtkRequisition nat_req, bold_req;
+       GtkRequisition nat_min, bold_min;
+       NautilusPathbarButtonLabel *self;
+
+       self = NAUTILUS_PATHBAR_BUTTON_LABEL(widget);
+       *minimum = *natural = 0;
+
+       gtk_widget_get_preferred_size (GTK_WIDGET(self->priv->label), &nat_min, &nat_req);
+       gtk_widget_get_preferred_size (GTK_WIDGET(self->priv->bold_label), &bold_min, &bold_req);
+
+       width = MAX (nat_req.width, bold_req.width);
+       *natural = MIN (width, NAUTILUS_PATH_BAR_LABEL_MAX_WIDTH);
+       g_print("mins %i %i %i %i\n", nat_min, nat_req, bold_min, bold_req);
+}
+
+static void
+nautilus_pathbar_button_label_get_preferred_height (GtkWidget *widget,
+                                                   gint      *minimum,
+                                                   gint      *natural)
+{
+       int height;
+       GtkRequisition nat_req, bold_req;
+       NautilusPathbarButtonLabel *self;
+
+       self = NAUTILUS_PATHBAR_BUTTON_LABEL(widget);
+       *minimum = *natural = 0;
+
+       gtk_widget_get_preferred_size (GTK_WIDGET(self->priv->label), NULL, &nat_req);
+       gtk_widget_get_preferred_size (GTK_WIDGET(self->priv->bold_label), &bold_req, NULL);
+
+       *natural = MAX (nat_req.height, bold_req.height);
+}
+
+static void
+nautilus_pathbar_button_label_class_init (NautilusPathbarButtonLabelClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+       GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+       object_class->finalize = nautilus_pathbar_button_label_finalize;
+
+       widget_class->get_preferred_width = nautilus_pathbar_button_label_get_preferred_width;
+       widget_class->get_preferred_height = nautilus_pathbar_button_label_get_preferred_height;
+}
+
+static void
+nautilus_pathbar_button_label_init (NautilusPathbarButtonLabel *self)
+{
+       self->priv = nautilus_pathbar_button_label_get_instance_private (self);
+
+       self->priv->label = gtk_label_new(NULL);
+       self->priv->bold_label = gtk_label_new(NULL);
+
+       gtk_label_set_ellipsize (self->priv->label, PANGO_ELLIPSIZE_MIDDLE);
+       //gtk_label_set_ellipsize (self->priv->bold_label, PANGO_ELLIPSIZE_MIDDLE);
+       gtk_label_set_single_line_mode (self->priv->label, TRUE);
+       gtk_label_set_single_line_mode (self->priv->bold_label, TRUE);
+       gtk_widget_set_no_show_all (GTK_WIDGET(self->priv->bold_label), TRUE);
+
+       gtk_box_pack_start(GTK_BOX(self), GTK_WIDGET(self->priv->label), FALSE, FALSE, 0);
+       gtk_box_pack_start(GTK_BOX(self), GTK_WIDGET(self->priv->bold_label), FALSE, FALSE, 0);
+}
diff --git a/src/nautilus-pathbar-button-label.h b/src/nautilus-pathbar-button-label.h
new file mode 100644
index 0000000..4a5f657
--- /dev/null
+++ b/src/nautilus-pathbar-button-label.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* nautilus-pathbar-button-label.h
+ *
+ * Copyright (C) 2014  Carlos Soriano <carlos soriano89 gmail com>
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors Carlos Soriano <carlos soriano89 gmail com>
+ */
+
+#ifndef NAUTILUS_PATHBAR_BUTTON_LABEL_H
+#define NAUTILUS_PATHBAR_BUTTON_LABEL_H
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define NAUTILUS_TYPE_PATHBAR_BUTTON_LABEL            (nautilus_pathbar_button_label_get_type())
+#define NAUTILUS_PATHBAR_BUTTON_LABEL(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
NAUTILUS_TYPE_PATHBAR_BUTTON_LABEL, NautilusPathbarButtonLabel))
+#define NAUTILUS_PATHBAR_BUTTON_LABEL_CONST(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
NAUTILUS_TYPE_PATHBAR_BUTTON_LABEL, NautilusPathbarButtonLabel const))
+#define NAUTILUS_PATHBAR_BUTTON_LABEL_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  
NAUTILUS_TYPE_PATHBAR_BUTTON_LABEL, NautilusPathbarButtonLabelClass))
+#define NAUTILUS_IS_PATHBAR_BUTTON_LABEL(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), 
NAUTILUS_TYPE_PATHBAR_BUTTON_LABEL))
+#define NAUTILUS_IS_PATHBAR_BUTTON_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  
NAUTILUS_TYPE_PATHBAR_BUTTON_LABEL))
+#define NAUTILUS_PATHBAR_BUTTON_LABEL_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  
NAUTILUS_TYPE_PATHBAR_BUTTON_LABEL, NautilusPathbarButtonLabelClass))
+
+typedef struct _NautilusPathbarButtonLabel        NautilusPathbarButtonLabel;
+typedef struct _NautilusPathbarButtonLabelClass   NautilusPathbarButtonLabelClass;
+typedef struct _NautilusPathbarButtonLabelPrivate NautilusPathbarButtonLabelPrivate;
+
+struct _NautilusPathbarButtonLabel
+{
+       GtkBox parent;
+
+       /*< private >*/
+       NautilusPathbarButtonLabelPrivate *priv;
+};
+
+struct _NautilusPathbarButtonLabelClass
+{
+       GtkBoxClass parent;
+};
+
+GType nautilus_pathbar_button_label_get_type (void) G_GNUC_CONST;
+NautilusPathbarButtonLabel *nautilus_pathbar_button_label_new (void);
+
+void nautilus_pathbar_button_label_set_text(NautilusPathbarButtonLabel *self,
+                                           gchar *dir_name);
+void nautilus_pathbar_button_label_set_bold(NautilusPathbarButtonLabel *self,
+                                           gboolean                   *bold);
+
+G_END_DECLS
+
+#endif /* NAUTILUS_PATHBAR_BUTTON_LABEL_H */
diff --git a/src/nautilus-pathbar.c b/src/nautilus-pathbar.c
index a0eed27..dbd8c24 100644
--- a/src/nautilus-pathbar.c
+++ b/src/nautilus-pathbar.c
@@ -24,6 +24,7 @@
 #include <gio/gio.h>
 
 #include "nautilus-pathbar.h"
+#include "nautilus-pathbar-button-label.h"
 
 #include <libnautilus-private/nautilus-file.h>
 #include <libnautilus-private/nautilus-file-utilities.h>
@@ -54,7 +55,6 @@ typedef enum {
 static guint path_bar_signals [LAST_SIGNAL] = { 0 };
 
 #define NAUTILUS_PATH_BAR_ICON_SIZE 16
-#define NAUTILUS_PATH_BAR_BUTTON_MAX_WIDTH 250
 
 typedef struct {
         GtkWidget *button;
@@ -298,29 +298,6 @@ get_dir_name (ButtonData *button_data)
        }
 }
 
-/* We always want to request the same size for the label, whether
- * or not the contents are bold
- */
-static void
-set_label_size_request (ButtonData *button_data)
-{
-        gint width, height;
-       GtkRequisition nat_req, bold_req;
-
-       if (button_data->label == NULL) {
-               return;
-       }
-
-       gtk_widget_get_preferred_size (button_data->label, NULL, &nat_req);
-       gtk_widget_get_preferred_size (button_data->bold_label, &bold_req, NULL);
-
-       width = MAX (nat_req.width, bold_req.width);
-       width = MIN (width, NAUTILUS_PATH_BAR_BUTTON_MAX_WIDTH);
-       height = MAX (nat_req.height, bold_req.height);
-
-       gtk_widget_set_size_request (button_data->label, width, height);
-}
-
 /* Size requisition:
  * 
  * Ideally, our size is determined by another widget, and we are just filling
@@ -345,7 +322,6 @@ nautilus_path_bar_get_preferred_width (GtkWidget *widget,
 
        for (list = path_bar->priv->button_list; list; list = list->next) {
                button_data = BUTTON_DATA (list->data);
-               set_label_size_request (button_data);
 
                gtk_widget_get_preferred_width (button_data->button, &child_min, &child_nat);
                gtk_widget_get_preferred_height (button_data->button, &child_height, NULL);
@@ -354,7 +330,7 @@ nautilus_path_bar_get_preferred_width (GtkWidget *widget,
                if (button_data->type == NORMAL_BUTTON) {
                        /* Use 2*Height as button width because of ellipsized label.  */
                        child_min = MAX (child_min, child_height * 2);
-                       child_nat = MAX (child_min, child_height * 2);
+                       child_nat = MAX (child_nat, child_height * 2);
                }
 
                *minimum = MAX (*minimum, child_min);
@@ -389,7 +365,6 @@ nautilus_path_bar_get_preferred_height (GtkWidget *widget,
 
        for (list = path_bar->priv->button_list; list; list = list->next) {
                button_data = BUTTON_DATA (list->data);
-               set_label_size_request (button_data);
 
                gtk_widget_get_preferred_height (button_data->button, &child_min, &child_nat);
 
@@ -527,12 +502,12 @@ nautilus_path_bar_size_allocate (GtkWidget     *widget,
        width = 0;
 
        gtk_widget_get_preferred_size (BUTTON_DATA (path_bar->priv->button_list->data)->button,
-                                      &child_requisition, NULL);
+                                      NULL, &child_requisition);
        width += child_requisition.width;
 
         for (list = path_bar->priv->button_list->next; list; list = list->next) {
                child = BUTTON_DATA (list->data)->button;
-               gtk_widget_get_preferred_size (child, &child_requisition, NULL);
+               gtk_widget_get_preferred_size (child, NULL, &child_requisition);
                 width += child_requisition.width;
         }
 
@@ -557,12 +532,12 @@ nautilus_path_bar_size_allocate (GtkWidget     *widget,
                        */
                /* Count down the path chain towards the end. */
                gtk_widget_get_preferred_size (BUTTON_DATA (first_button->data)->button,
-                                              &child_requisition, NULL);
+                                              NULL, &child_requisition);
                 width = child_requisition.width;
                 list = first_button->prev;
                 while (list && !reached_end) {
                        child = BUTTON_DATA (list->data)->button;
-                       gtk_widget_get_preferred_size (child, &child_requisition, NULL);
+                       gtk_widget_get_preferred_size (child, NULL, &child_requisition);
 
                        if (width + child_requisition.width + slider_space > allocation->width) {
                                reached_end = TRUE;
@@ -577,7 +552,7 @@ nautilus_path_bar_size_allocate (GtkWidget     *widget,
 
                 while (first_button->next && ! reached_end) {
                        child = BUTTON_DATA (first_button->next->data)->button;
-                       gtk_widget_get_preferred_size (child, &child_requisition, NULL);
+                       gtk_widget_get_preferred_size (child, NULL, &child_requisition);
 
                        if (width + child_requisition.width + slider_space > allocation->width) {
                                reached_end = TRUE;
@@ -614,7 +589,7 @@ nautilus_path_bar_size_allocate (GtkWidget     *widget,
 
         for (list = first_button; list; list = list->prev) {
                 child = BUTTON_DATA (list->data)->button;
-               gtk_widget_get_preferred_size (child, &child_requisition, NULL);
+               gtk_widget_get_preferred_size (child, NULL, &child_requisition);
 
                 child_allocation.width = MIN (child_requisition.width, largest_width);
                 if (direction == GTK_TEXT_DIR_RTL) {
@@ -632,7 +607,6 @@ nautilus_path_bar_size_allocate (GtkWidget     *widget,
                                }       
                        }
                }
-
                needs_reorder |= gtk_widget_get_child_visible (child) == FALSE;
                 gtk_widget_set_child_visible (child, TRUE);
                 gtk_widget_size_allocate (child, &child_allocation);
@@ -1379,19 +1353,9 @@ nautilus_path_bar_update_button_appearance (ButtonData *button_data)
         const gchar *dir_name = get_dir_name (button_data);
        GIcon *icon;
 
-        if (button_data->label != NULL) {
-               char *markup;
-
-               markup = g_markup_printf_escaped ("<b>%s</b>", dir_name);
-
-                if (gtk_label_get_use_markup (GTK_LABEL (button_data->label))) {
-                       gtk_label_set_markup (GTK_LABEL (button_data->label), markup);
-               } else {
-                       gtk_label_set_text (GTK_LABEL (button_data->label), dir_name);
-               }
-
-               gtk_label_set_markup (GTK_LABEL (button_data->bold_label), markup);
-               g_free (markup);
+       if (button_data->label != NULL) {
+               nautilus_pathbar_button_label_set_text(NAUTILUS_PATHBAR_BUTTON_LABEL(button_data->label),
+                                                      dir_name);
         }
 
        icon = get_gicon (button_data);
@@ -1409,11 +1373,9 @@ nautilus_path_bar_update_button_state (ButtonData *button_data,
                                       gboolean    current_dir)
 {
        if (button_data->label != NULL) {
-               gtk_label_set_label (GTK_LABEL (button_data->label), NULL);
-               gtk_label_set_label (GTK_LABEL (button_data->bold_label), NULL);
-               gtk_label_set_use_markup (GTK_LABEL (button_data->label), current_dir);
+               nautilus_pathbar_button_label_set_bold(NAUTILUS_PATHBAR_BUTTON_LABEL(button_data->label),
+                                                      current_dir);
        }
-
        nautilus_path_bar_update_button_appearance (button_data);
 
         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_data->button)) != current_dir) {
@@ -1643,23 +1605,13 @@ make_button_data (NautilusPathBar  *path_bar,
                case MOUNT_BUTTON:
                case NORMAL_BUTTON:
                default:
-                       button_data->label = gtk_label_new (NULL);
+                       button_data->label = nautilus_pathbar_button_label_new ();
                         child = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
                        gtk_box_pack_start (GTK_BOX (child), button_data->image, FALSE, FALSE, 0);
                        gtk_box_pack_start (GTK_BOX (child), button_data->label, FALSE, FALSE, 0);
                        break;
         }
 
-       if (button_data->label != NULL) {
-               gtk_label_set_ellipsize (GTK_LABEL (button_data->label), PANGO_ELLIPSIZE_MIDDLE);
-               gtk_label_set_single_line_mode (GTK_LABEL (button_data->label), TRUE);
-
-               button_data->bold_label = gtk_label_new (NULL);
-               gtk_widget_set_no_show_all (button_data->bold_label, TRUE);
-               gtk_label_set_single_line_mode (GTK_LABEL (button_data->bold_label), TRUE);
-               gtk_box_pack_start (GTK_BOX (child), button_data->bold_label, FALSE, FALSE, 0);
-       }
-
        if (button_data->path == NULL) {
                button_data->path = g_object_ref (path);
        }


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