diff options
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/nautilus-pathbar-button-label.c | 175 | ||||
-rw-r--r-- | src/nautilus-pathbar-button-label.h | 65 | ||||
-rw-r--r-- | src/nautilus-pathbar.c | 81 |
4 files changed, 260 insertions, 63 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 2aaea2450..424abb045 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 000000000..0d3e6441e --- /dev/null +++ b/src/nautilus-pathbar-button-label.c @@ -0,0 +1,175 @@ +/* -*- 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); + // We have to show the widget temporary to get a valid size requirement + //gtk_widget_show(GTK_WIDGET(self->priv->bold_label)); + gtk_widget_get_preferred_size (GTK_WIDGET(self->priv->bold_label), &bold_min, &bold_req); + //gtk_widget_hide(GTK_WIDGET(self->priv->bold_label)); + + width = MAX (nat_req.width, bold_req.width); + *natural = MIN (width, NAUTILUS_PATH_BAR_LABEL_MAX_WIDTH); + *minimum = MAX (nat_min.width, bold_min.width); + g_print("mins %i %i %i %i\n", nat_min.width, nat_req.width, bold_min.width, bold_req.width); +} + +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); + // We have to show the widget temporary to get a valid size requirement + //gtk_widget_show(GTK_WIDGET(self->priv->bold_label)); + gtk_widget_get_preferred_size (GTK_WIDGET(self->priv->bold_label), &bold_req, NULL); + //gtk_widget_hide(GTK_WIDGET(self->priv->bold_label)); + + *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 000000000..4a5f65784 --- /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 a0eed276c..2eebc43b6 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,16 +502,19 @@ 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; } - if (width <= allocation->width) { + // Either we have enough width, or there's only one button, so we don't + // require sliders. + if (width <= allocation->width || + (!path_bar->priv->button_list || path_bar->priv->button_list->next == NULL)) { first_button = g_list_last (path_bar->priv->button_list); } else { gboolean reached_end; @@ -557,12 +535,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 +555,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 +592,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 +610,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 +1356,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 +1376,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 +1608,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); } |