diff --git a/ChangeLog b/ChangeLog index 4f5d2a46b48625ec9a6b179f2924a8df07dfedbe..41bbd6dea2f30d72cc0690bd7b937a1d0647ad34 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +2005-08-18 Benedikt Meurer <benny@xfce.org> + + * thunarx/thunarx-gdk-pixbuf-extensions.{c,h}: Add new function + thunarx_gdk_pixbuf_spotlight(), which is used to create a + special icon for the Gtk prelight state. + * thunar/thunar-icon-renderer.{c,h}, thunar/Makefile.am, + thunar/thunar-details-view.c, po/POTFILES.in: Rename + ThunarDetailsViewIconRenderer to ThunarIconRenderer, as + it will also be used by the icon view now. + * thunar/thunar-text-renderer.{c,h}, thunar/Makefile.am, + thunar/thunar-details-view.c, po/POTFILES.in: Rename + ThunarDetailsViewTextRenderer to ThunarTextRenderer, + as it will also be used by the icon view now. + * thunar/thunar-icon-renderer.{c,h}, thunar/thunar-text-renderer.{c,h}: + Add required functionality to use these renderers with the new + ExoIconView. + * thunar/thunar-icon-view.c: Update to use the new ExoIconView class, + with the modified ThunarIconRenderer and ThunarTextRenderer. + * thunar/thunar-launcher.h, thunar/thunar-open-with-action.h: Use + G_GNUC_MALLOC instead of EXO_GNUC_MALLOC. + * thunar/thunar-window.c(thunar_window_init): Use the icon view by + default for testing now. + * configure.in.in: Bump version to 0.1.2. + * thunar/thunar-window.c(thunar_window_action_about): Switch to + GtkAboutDialog. + 2005-08-18 Benedikt Meurer <benny@xfce.org> * thunar/thunar-list-model.c(thunar_list_model_files_added): Speed up diff --git a/configure.in.in b/configure.in.in index d191ee978ed26682dc06b9ea790c112baa11bfbf..84cad84bb0c0a4fc69cbe05b9e9d650bf1114a96 100644 --- a/configure.in.in +++ b/configure.in.in @@ -13,7 +13,7 @@ m4_define([thunar_verinfo], [0:0:0]) m4_define([thunar_version_api], [1]) m4_define([thunar_version_major], [0]) m4_define([thunar_version_minor], [1]) -m4_define([thunar_version_micro], [1]) +m4_define([thunar_version_micro], [2]) m4_define([thunar_version_build], [r@REVISION@]) m4_define([thunar_version_tag], [svn]) m4_define([thunar_version], [thunar_version_major().thunar_version_minor().thunar_version_micro()ifelse(thunar_version_tag(), [], [], [thunar_version_tag()-thunar_version_build()])]) diff --git a/po/POTFILES.in b/po/POTFILES.in index 6d5753680e2e70936aab331ba053e3b5fd53e67a..a7ba0f86408acbbd3b4eb433c800f7e6371d106f 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -47,10 +47,6 @@ thunar/thunar-desktop-view.c thunar/thunar-desktop-view.h thunar/thunar-desktop-window.c thunar/thunar-desktop-window.h -thunar/thunar-details-view-icon-renderer.c -thunar/thunar-details-view-icon-renderer.h -thunar/thunar-details-view-text-renderer.c -thunar/thunar-details-view-text-renderer.h thunar/thunar-details-view.c thunar/thunar-details-view.h thunar/thunar-favourites-model.c @@ -65,6 +61,8 @@ thunar/thunar-folder.c thunar/thunar-folder.h thunar/thunar-icon-factory.c thunar/thunar-icon-factory.h +thunar/thunar-icon-renderer.c +thunar/thunar-icon-renderer.h thunar/thunar-icon-view.c thunar/thunar-icon-view.h thunar/thunar-launcher.c @@ -101,6 +99,8 @@ thunar/thunar-standard-view.c thunar/thunar-standard-view.h thunar/thunar-statusbar.c thunar/thunar-statusbar.h +thunar/thunar-text-renderer.c +thunar/thunar-text-renderer.h thunar/thunar-trash-file.c thunar/thunar-trash-file.h thunar/thunar-trash-folder.c diff --git a/thunar/Makefile.am b/thunar/Makefile.am index aafaafaab71f04a45115de79b44d94bb62390f46..638aaae886086cf20146fc303d4fe68ee08aecba 100644 --- a/thunar/Makefile.am +++ b/thunar/Makefile.am @@ -26,10 +26,6 @@ Thunar_SOURCES = \ thunar-desktop-window.h \ thunar-details-view.c \ thunar-details-view.h \ - thunar-details-view-icon-renderer.c \ - thunar-details-view-icon-renderer.h \ - thunar-details-view-text-renderer.c \ - thunar-details-view-text-renderer.h \ thunar-fallback-icon.c \ thunar-fallback-icon.h \ thunar-favourites-model.c \ @@ -44,6 +40,8 @@ Thunar_SOURCES = \ thunar-folder.h \ thunar-icon-factory.c \ thunar-icon-factory.h \ + thunar-icon-renderer.c \ + thunar-icon-renderer.h \ thunar-icon-view.c \ thunar-icon-view.h \ thunar-launcher.c \ @@ -81,6 +79,8 @@ Thunar_SOURCES = \ thunar-standard-view-ui.h \ thunar-statusbar.c \ thunar-statusbar.h \ + thunar-text-renderer.c \ + thunar-text-renderer.h \ thunar-trash-file.c \ thunar-trash-file.h \ thunar-trash-folder.c \ diff --git a/thunar/thunar-details-view-icon-renderer.c b/thunar/thunar-details-view-icon-renderer.c deleted file mode 100644 index c3331c8f9fac083e0c6df9457bc9f6278c511a77..0000000000000000000000000000000000000000 --- a/thunar/thunar-details-view-icon-renderer.c +++ /dev/null @@ -1,360 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <thunar/thunar-details-view-icon-renderer.h> -#include <thunar/thunar-file.h> -#include <thunar/thunar-icon-factory.h> - - - -enum -{ - PROP_0, - PROP_FILE, - PROP_SIZE, -}; - - - -static void thunar_details_view_icon_renderer_class_init (ThunarDetailsViewIconRendererClass *klass); -static void thunar_details_view_icon_renderer_init (ThunarDetailsViewIconRenderer *icon_renderer); -static void thunar_details_view_icon_renderer_finalize (GObject *object); -static void thunar_details_view_icon_renderer_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void thunar_details_view_icon_renderer_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void thunar_details_view_icon_renderer_get_size (GtkCellRenderer *renderer, - GtkWidget *widget, - GdkRectangle *rectangle, - gint *x_offset, - gint *y_offset, - gint *width, - gint *height); -static void thunar_details_view_icon_renderer_render (GtkCellRenderer *renderer, - GdkWindow *window, - GtkWidget *widget, - GdkRectangle *background_area, - GdkRectangle *cell_area, - GdkRectangle *expose_area, - GtkCellRendererState flags); - - - -struct _ThunarDetailsViewIconRendererClass -{ - GtkCellRendererClass __parent__; -}; - -struct _ThunarDetailsViewIconRenderer -{ - GtkCellRenderer __parent__; - - ThunarFile *file; - gint size; -}; - - - -G_DEFINE_TYPE (ThunarDetailsViewIconRenderer, thunar_details_view_icon_renderer, GTK_TYPE_CELL_RENDERER); - - - -static void -thunar_details_view_icon_renderer_class_init (ThunarDetailsViewIconRendererClass *klass) -{ - GtkCellRendererClass *gtkcell_renderer_class; - GObjectClass *gobject_class; - - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = thunar_details_view_icon_renderer_finalize; - gobject_class->get_property = thunar_details_view_icon_renderer_get_property; - gobject_class->set_property = thunar_details_view_icon_renderer_set_property; - - gtkcell_renderer_class = GTK_CELL_RENDERER_CLASS (klass); - gtkcell_renderer_class->get_size = thunar_details_view_icon_renderer_get_size; - gtkcell_renderer_class->render = thunar_details_view_icon_renderer_render; - - /** - * ThunarDetailsViewIconRenderer:file: - * - * The file whose icon to render. - **/ - g_object_class_install_property (gobject_class, - PROP_FILE, - g_param_spec_object ("file", - _("File"), - _("The file whose icon to render"), - THUNAR_TYPE_FILE, - EXO_PARAM_READWRITE)); - - /** - * ThunarDetailsViewIconRenderer:icon-size: - * - * The icon size in pixels. - **/ - g_object_class_install_property (gobject_class, - PROP_SIZE, - g_param_spec_int ("size", - _("Icon size"), - _("The icon size in pixels"), - 1, G_MAXINT, 24, - EXO_PARAM_READWRITE)); -} - - - -static void -thunar_details_view_icon_renderer_init (ThunarDetailsViewIconRenderer *icon_renderer) -{ - icon_renderer->size = 24; -} - - - -static void -thunar_details_view_icon_renderer_finalize (GObject *object) -{ - ThunarDetailsViewIconRenderer *icon_renderer = THUNAR_DETAILS_VIEW_ICON_RENDERER (object); - - /* free the icon data */ - if (G_LIKELY (icon_renderer->file != NULL)) - g_object_unref (G_OBJECT (icon_renderer->file)); - - G_OBJECT_CLASS (thunar_details_view_icon_renderer_parent_class)->finalize (object); -} - - - -static void -thunar_details_view_icon_renderer_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ThunarDetailsViewIconRenderer *icon_renderer = THUNAR_DETAILS_VIEW_ICON_RENDERER (object); - - switch (prop_id) - { - case PROP_FILE: - g_value_set_object (value, icon_renderer->file); - break; - - case PROP_SIZE: - g_value_set_int (value, icon_renderer->size); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - - - -static void -thunar_details_view_icon_renderer_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ThunarDetailsViewIconRenderer *icon_renderer = THUNAR_DETAILS_VIEW_ICON_RENDERER (object); - - switch (prop_id) - { - case PROP_FILE: - if (G_LIKELY (icon_renderer->file != NULL)) - g_object_unref (G_OBJECT (icon_renderer->file)); - icon_renderer->file = g_value_get_object (value); - if (G_LIKELY (icon_renderer->file != NULL)) - g_object_ref (G_OBJECT (icon_renderer->file)); - break; - - case PROP_SIZE: - icon_renderer->size = g_value_get_int (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - - - - -static void -thunar_details_view_icon_renderer_get_size (GtkCellRenderer *renderer, - GtkWidget *widget, - GdkRectangle *rectangle, - gint *x_offset, - gint *y_offset, - gint *width, - gint *height) -{ - ThunarDetailsViewIconRenderer *icon_renderer = THUNAR_DETAILS_VIEW_ICON_RENDERER (renderer); - - if (rectangle != NULL) - { - if (x_offset != NULL) - { - *x_offset = ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ? 1.0 - renderer->xalign : renderer->xalign) - * (rectangle->width - icon_renderer->size); - *x_offset = MAX (*x_offset, 0) + renderer->xpad; - } - - if (y_offset != NULL) - { - *y_offset = renderer->yalign * (rectangle->height - icon_renderer->size); - *y_offset = MAX (*y_offset, 0) + renderer->ypad; - } - } - else - { - if (x_offset != NULL) - *x_offset = 0; - - if (y_offset != NULL) - *y_offset = 0; - } - - if (G_LIKELY (width != NULL)) - *width = (gint) renderer->xpad * 2 + icon_renderer->size; - - if (G_LIKELY (height != NULL)) - *height = (gint) renderer->ypad * 2 + icon_renderer->size; -} - - - -static void -thunar_details_view_icon_renderer_render (GtkCellRenderer *renderer, - GdkWindow *window, - GtkWidget *widget, - GdkRectangle *background_area, - GdkRectangle *cell_area, - GdkRectangle *expose_area, - GtkCellRendererState flags) -{ - ThunarDetailsViewIconRenderer *icon_renderer = THUNAR_DETAILS_VIEW_ICON_RENDERER (renderer); - ThunarIconFactory *icon_factory; - GdkRectangle icon_area; - GdkRectangle draw_area; - GdkPixbuf *scaled; - GdkPixbuf *icon; - GList *emblems; - GList *lp; - - if (G_UNLIKELY (icon_renderer->file == NULL)) - return; - - /* load the main icon */ - icon_factory = thunar_icon_factory_get_default (); - icon = thunar_file_load_icon (icon_renderer->file, icon_factory, icon_renderer->size); - if (G_UNLIKELY (icon == NULL)) - return; - - icon_area.width = gdk_pixbuf_get_width (icon); - icon_area.height = gdk_pixbuf_get_height (icon); - - /* scale down the icon on-demand */ - if (G_UNLIKELY (icon_area.width > icon_renderer->size || icon_area.height > icon_renderer->size)) - { - scaled = exo_gdk_pixbuf_scale_ratio (icon, icon_renderer->size); - g_object_unref (G_OBJECT (icon)); - icon = scaled; - - icon_area.width = gdk_pixbuf_get_width (icon); - icon_area.height = gdk_pixbuf_get_height (icon); - } - - icon_area.x = cell_area->x + (cell_area->width - icon_area.width) / 2; - icon_area.y = cell_area->y + (cell_area->height - icon_area.height) / 2; - - if (gdk_rectangle_intersect (cell_area, &icon_area, &draw_area) - && gdk_rectangle_intersect (expose_area, &icon_area, &draw_area)) - { - gdk_draw_pixbuf (window, widget->style->black_gc, icon, - draw_area.x - icon_area.x, draw_area.y - icon_area.y, - draw_area.x, draw_area.y, draw_area.width, draw_area.height, - GDK_RGB_DITHER_NORMAL, 0, 0); - } - - g_object_unref (G_OBJECT (icon)); - - /* display the primary emblem as well (if any) */ - emblems = thunar_file_get_emblem_names (icon_renderer->file); - if (emblems != NULL) - { - /* lookup the first emblem icon that exits in the icon theme */ - for (icon = NULL, lp = emblems; lp != NULL; lp = lp->next) - { - icon = thunar_icon_factory_load_icon (icon_factory, lp->data, icon_renderer->size, NULL, FALSE); - if (G_LIKELY (icon != NULL)) - break; - } - - if (G_LIKELY (icon != NULL)) - { - icon_area.width = gdk_pixbuf_get_width (icon); - icon_area.height = gdk_pixbuf_get_height (icon); - icon_area.x = cell_area->x + (cell_area->width - icon_area.width - renderer->xpad); - icon_area.y = cell_area->y + (cell_area->height - icon_area.height - renderer->ypad); - - if (gdk_rectangle_intersect (expose_area, &icon_area, &draw_area)) - { - gdk_draw_pixbuf (window, widget->style->black_gc, icon, - draw_area.x - icon_area.x, draw_area.y - icon_area.y, - draw_area.x, draw_area.y, draw_area.width, draw_area.height, - GDK_RGB_DITHER_NORMAL, 0, 0); - } - - g_object_unref (G_OBJECT (icon)); - } - - g_list_free (emblems); - } -} - - - -/** - * thunar_details_view_icon_renderer_new: - * - * Creates a new #ThunarDetailsViewIconRenderer. Adjust rendering - * parameters using object properties. Object properties can be - * set globally with #g_object_set. Also, with #GtkTreeViewColumn, - * you can bind a property to a value in a #GtkTreeModel. - * - * Return value: the newly allocated #ThunarDetailsViewIconRenderer. - **/ -GtkCellRenderer* -thunar_details_view_icon_renderer_new (void) -{ - return g_object_new (THUNAR_TYPE_DETAILS_VIEW_ICON_RENDERER, NULL); -} - - diff --git a/thunar/thunar-details-view-icon-renderer.h b/thunar/thunar-details-view-icon-renderer.h deleted file mode 100644 index 9f366df2be3a33ed2d57ecd3e0a6d2d768c3b468..0000000000000000000000000000000000000000 --- a/thunar/thunar-details-view-icon-renderer.h +++ /dev/null @@ -1,43 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __THUNAR_DETAILS_VIEW_ICON_RENDERER_H__ -#define __THUNAR_DETAILS_VIEW_ICON_RENDERER_H__ - -#include <gtk/gtk.h> - -G_BEGIN_DECLS; - -typedef struct _ThunarDetailsViewIconRendererClass ThunarDetailsViewIconRendererClass; -typedef struct _ThunarDetailsViewIconRenderer ThunarDetailsViewIconRenderer; - -#define THUNAR_TYPE_DETAILS_VIEW_ICON_RENDERER (thunar_details_view_icon_renderer_get_type ()) -#define THUNAR_DETAILS_VIEW_ICON_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_DETAILS_VIEW_ICON_RENDERER, ThunarDetailsViewIconRenderer)) -#define THUNAR_DETAILS_VIEW_ICON_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_DETAILS_VIEW_ICON_RENDERER, ThunarDetailsViewIconRendererClass)) -#define THUNAR_IS_DETAILS_VIEW_ICON_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_DETAILS_VIEW_ICON_RENDERER)) -#define THUNAR_IS_DETAILS_VIEW_ICON_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_DETAILS_VIEW_ICON_RENDERER)) -#define THUNAR_DETAILS_VIEW_ICON_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_DETAILS_VIEW_ICON_RENDERER, ThunarDetailsViewIconRendererClass)) - -GType thunar_details_view_icon_renderer_get_type (void) G_GNUC_CONST; - -GtkCellRenderer *thunar_details_view_icon_renderer_new (void) G_GNUC_MALLOC; - -G_END_DECLS; - -#endif /* !__THUNAR_DETAILS_VIEW_ICON_RENDERER_H__ */ diff --git a/thunar/thunar-details-view-text-renderer.c b/thunar/thunar-details-view-text-renderer.c deleted file mode 100644 index 9ac97eaabaa73bfad7cdff9fb33991c3add17906..0000000000000000000000000000000000000000 --- a/thunar/thunar-details-view-text-renderer.c +++ /dev/null @@ -1,388 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <exo/exo.h> - -#include <thunar/thunar-details-view-text-renderer.h> - - - -enum -{ - PROP_0, - PROP_TEXT, -}; - - - -static void thunar_details_view_text_renderer_class_init (ThunarDetailsViewTextRendererClass *klass); -static void thunar_details_view_text_renderer_finalize (GObject *object); -static void thunar_details_view_text_renderer_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void thunar_details_view_text_renderer_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void thunar_details_view_text_renderer_get_size (GtkCellRenderer *renderer, - GtkWidget *widget, - GdkRectangle *cell_area, - gint *x_offset, - gint *y_offset, - gint *width, - gint *height); -static void thunar_details_view_text_renderer_render (GtkCellRenderer *renderer, - GdkWindow *window, - GtkWidget *widget, - GdkRectangle *background_area, - GdkRectangle *cell_area, - GdkRectangle *expose_area, - GtkCellRendererState flags); -static void thunar_details_view_text_renderer_invalidate (ThunarDetailsViewTextRenderer *text_renderer); -static void thunar_details_view_text_renderer_set_widget (ThunarDetailsViewTextRenderer *text_renderer, - GtkWidget *widget); - - - -struct _ThunarDetailsViewTextRendererClass -{ - GtkCellRendererClass __parent__; -}; - -struct _ThunarDetailsViewTextRenderer -{ - GtkCellRenderer __parent__; - - PangoLayout *layout; - GtkWidget *widget; - gchar text[256]; - gint char_width; - gint char_height; -}; - - - -static GObjectClass *thunar_details_view_text_renderer_parent_class; - - - -GType -thunar_details_view_text_renderer_get_type (void) -{ - static GType type = G_TYPE_INVALID; - - if (G_UNLIKELY (type == G_TYPE_INVALID)) - { - static const GTypeInfo info = - { - sizeof (ThunarDetailsViewTextRendererClass), - NULL, - NULL, - (GClassInitFunc) thunar_details_view_text_renderer_class_init, - NULL, - NULL, - sizeof (ThunarDetailsViewTextRenderer), - 0, - NULL, - NULL, - }; - - type = g_type_register_static (GTK_TYPE_CELL_RENDERER, "ThunarDetailsViewTextRenderer", &info, 0); - } - - return type; -} - - - -static void -thunar_details_view_text_renderer_class_init (ThunarDetailsViewTextRendererClass *klass) -{ - GtkCellRendererClass *gtkcell_renderer_class; - GObjectClass *gobject_class; - - thunar_details_view_text_renderer_parent_class = g_type_class_peek_parent (klass); - - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = thunar_details_view_text_renderer_finalize; - gobject_class->get_property = thunar_details_view_text_renderer_get_property; - gobject_class->set_property = thunar_details_view_text_renderer_set_property; - - gtkcell_renderer_class = GTK_CELL_RENDERER_CLASS (klass); - gtkcell_renderer_class->get_size = thunar_details_view_text_renderer_get_size; - gtkcell_renderer_class->render = thunar_details_view_text_renderer_render; - - /** - * ThunarDetailsViewTextRenderer:text: - * - * The text to render. - **/ - g_object_class_install_property (gobject_class, - PROP_TEXT, - g_param_spec_string ("text", - _("Text"), - _("The text to render"), - NULL, - EXO_PARAM_READWRITE)); -} - - - -static void -thunar_details_view_text_renderer_finalize (GObject *object) -{ - ThunarDetailsViewTextRenderer *text_renderer = THUNAR_DETAILS_VIEW_TEXT_RENDERER (object); - - /* drop the cached widget */ - thunar_details_view_text_renderer_set_widget (text_renderer, NULL); - - G_OBJECT_CLASS (thunar_details_view_text_renderer_parent_class)->finalize (object); -} - - - -static void -thunar_details_view_text_renderer_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ThunarDetailsViewTextRenderer *text_renderer = THUNAR_DETAILS_VIEW_TEXT_RENDERER (object); - - switch (prop_id) - { - case PROP_TEXT: - g_value_set_string (value, text_renderer->text); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - - - -static void -thunar_details_view_text_renderer_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ThunarDetailsViewTextRenderer *text_renderer = THUNAR_DETAILS_VIEW_TEXT_RENDERER (object); - const gchar *sval; - - switch (prop_id) - { - case PROP_TEXT: - sval = g_value_get_string (value); - g_strlcpy (text_renderer->text, G_UNLIKELY (sval == NULL) ? "" : sval, sizeof (text_renderer->text)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - - - -static void -thunar_details_view_text_renderer_get_size (GtkCellRenderer *renderer, - GtkWidget *widget, - GdkRectangle *cell_area, - gint *x_offset, - gint *y_offset, - gint *width, - gint *height) -{ - ThunarDetailsViewTextRenderer *text_renderer = THUNAR_DETAILS_VIEW_TEXT_RENDERER (renderer); - gint text_length; - gint text_width; - gint text_height; - - /* setup the new widget */ - thunar_details_view_text_renderer_set_widget (text_renderer, widget); - - /* determine the text_length in characters */ - text_length = g_utf8_strlen (text_renderer->text, -1); - - /* calculate the appromixate text width/height */ - text_width = text_renderer->char_width * text_length; - text_height = text_renderer->char_height; - - /* update width/height */ - if (G_LIKELY (width != NULL)) - *width = text_width + 2 * renderer->xpad; - if (G_LIKELY (height != NULL)) - *height = text_height + 2 * renderer->ypad; - - /* update the x/y offsets */ - if (G_LIKELY (cell_area != NULL)) - { - if (G_LIKELY (x_offset != NULL)) - { - *x_offset = ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ? (1.0 - renderer->xalign) : renderer->xalign) - * (cell_area->width - text_width - (2 * renderer->xpad)); - *x_offset = MAX (*x_offset, 0); - } - - if (G_LIKELY (y_offset != NULL)) - { - *y_offset = renderer->yalign * (cell_area->height - text_height - (2 * renderer->ypad)); - *y_offset = MAX (*y_offset, 0); - } - } -} - - - -static void -thunar_details_view_text_renderer_render (GtkCellRenderer *renderer, - GdkWindow *window, - GtkWidget *widget, - GdkRectangle *background_area, - GdkRectangle *cell_area, - GdkRectangle *expose_area, - GtkCellRendererState flags) -{ - ThunarDetailsViewTextRenderer *text_renderer = THUNAR_DETAILS_VIEW_TEXT_RENDERER (renderer); - GtkStateType state; - gint text_width; - gint text_height; - gint x_offset; - gint y_offset; - - /* setup the new widget */ - thunar_details_view_text_renderer_set_widget (text_renderer, widget); - - if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED) - { - if (GTK_WIDGET_HAS_FOCUS (widget)) - state = GTK_STATE_SELECTED; - else - state = GTK_STATE_ACTIVE; - } - else if ((flags & GTK_CELL_RENDERER_PRELIT) == GTK_CELL_RENDERER_PRELIT - && GTK_WIDGET_STATE (widget) == GTK_STATE_PRELIGHT) - { - state = GTK_STATE_PRELIGHT; - } - else - { - if (GTK_WIDGET_STATE (widget) == GTK_STATE_INSENSITIVE) - state = GTK_STATE_INSENSITIVE; - else - state = GTK_STATE_NORMAL; - } - - pango_layout_set_text (text_renderer->layout, text_renderer->text, -1); - - /* calculate the real text dimension */ - pango_layout_get_pixel_size (text_renderer->layout, &text_width, &text_height); - - /* calculate the real x-offset */ - x_offset = ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ? (1.0 - renderer->xalign) : renderer->xalign) - * (cell_area->width - text_width - (2 * renderer->xpad)); - x_offset = MAX (x_offset, 0); - - /* calculate the real y-offset */ - y_offset = renderer->yalign * (cell_area->height - text_height - (2 * renderer->ypad)); - y_offset = MAX (y_offset, 0); - - gtk_paint_layout (widget->style, window, state, TRUE, - expose_area, widget, "cellrenderertext", - cell_area->x + x_offset + renderer->xpad, - cell_area->y + y_offset + renderer->ypad, - text_renderer->layout); -} - - - -static void -thunar_details_view_text_renderer_invalidate (ThunarDetailsViewTextRenderer *text_renderer) -{ - thunar_details_view_text_renderer_set_widget (text_renderer, NULL); -} - - - -static void -thunar_details_view_text_renderer_set_widget (ThunarDetailsViewTextRenderer *text_renderer, - GtkWidget *widget) -{ - // FIXME: The sample text should be translatable with a hint to translators! - static const gchar SAMPLE_TEXT[] = "The Quick Brown Fox Jumps Over the Lazy Dog"; - PangoRectangle extents; - - if (G_LIKELY (widget == text_renderer->widget)) - return; - - /* disconnect from the previously set widget */ - if (G_UNLIKELY (text_renderer->widget != NULL)) - { - g_signal_handlers_disconnect_by_func (G_OBJECT (text_renderer->widget), thunar_details_view_text_renderer_invalidate, text_renderer); - g_object_unref (G_OBJECT (text_renderer->layout)); - g_object_unref (G_OBJECT (text_renderer->widget)); - } - - /* activate the new widget */ - text_renderer->widget = widget; - - /* connect to the new widget */ - if (G_LIKELY (widget != NULL)) - { - /* take a reference on the widget */ - g_object_ref (G_OBJECT (widget)); - - /* we need to recalculate the metrics when a new style (and thereby a new font) is set */ - g_signal_connect_swapped (G_OBJECT (text_renderer->widget), "destroy", G_CALLBACK (thunar_details_view_text_renderer_invalidate), text_renderer); - g_signal_connect_swapped (G_OBJECT (text_renderer->widget), "style-set", G_CALLBACK (thunar_details_view_text_renderer_invalidate), text_renderer); - - /* calculate the average character dimensions */ - text_renderer->layout = gtk_widget_create_pango_layout (widget, SAMPLE_TEXT); - pango_layout_get_pixel_extents (text_renderer->layout, NULL, &extents); - pango_layout_set_width (text_renderer->layout, -1); - text_renderer->char_width = extents.width / g_utf8_strlen (SAMPLE_TEXT, sizeof (SAMPLE_TEXT) - 1); - text_renderer->char_height = extents.height; - } - else - { - text_renderer->layout = NULL; - text_renderer->char_width = 0; - text_renderer->char_height = 0; - } -} - - - -/** - * thunar_details_view_text_renderer_new: - **/ -GtkCellRenderer* -thunar_details_view_text_renderer_new (void) -{ - return g_object_new (THUNAR_TYPE_DETAILS_VIEW_TEXT_RENDERER, NULL); -} - diff --git a/thunar/thunar-details-view-text-renderer.h b/thunar/thunar-details-view-text-renderer.h deleted file mode 100644 index 8b03c62ef8df392dbcb5da3e0919e6ee1e222c26..0000000000000000000000000000000000000000 --- a/thunar/thunar-details-view-text-renderer.h +++ /dev/null @@ -1,43 +0,0 @@ -/* $Id$ */ -/*- - * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __THUNAR_DETAILS_VIEW_TEXT_RENDERER_H__ -#define __THUNAR_DETAILS_VIEW_TEXT_RENDERER_H__ - -#include <gtk/gtk.h> - -G_BEGIN_DECLS; - -typedef struct _ThunarDetailsViewTextRendererClass ThunarDetailsViewTextRendererClass; -typedef struct _ThunarDetailsViewTextRenderer ThunarDetailsViewTextRenderer; - -#define THUNAR_TYPE_DETAILS_VIEW_TEXT_RENDERER (thunar_details_view_text_renderer_get_type ()) -#define THUNAR_DETAILS_VIEW_TEXT_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_DETAILS_VIEW_TEXT_RENDERER, ThunarDetailsViewTextRenderer)) -#define THUNAR_DETAILS_VIEW_TEXT_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_DETAILS_VIEW_TEXT_RENDERER, ThunarDetailsViewTextRendererClass)) -#define THUNAR_IS_DETAILS_VIEW_TEXT_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_DETAILS_VIEW_TEXT_RENDERER)) -#define THUNAR_IS_DETAILS_VIEW_TEXT_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_DETAILS_VIEW_TEXT_RENDERER)) -#define THUNAR_DETAILS_VIEW_TEXT_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_DETAILS_VIEW_TEXT_RENDERER, ThunarDetailsViewTextRendererClass)) - -GType thunar_details_view_text_renderer_get_type (void) G_GNUC_CONST; - -GtkCellRenderer *thunar_details_view_text_renderer_new (void) G_GNUC_MALLOC; - -G_END_DECLS; - -#endif /* !__THUNAR_DETAILS_VIEW_TEXT_RENDERER_H__ */ diff --git a/thunar/thunar-details-view.c b/thunar/thunar-details-view.c index a67e53547ffd3a0824aa8ef8ca8449d7e74571ce..a0701a2ec2b996a2effa8dc8ae4f6eb318687912 100644 --- a/thunar/thunar-details-view.c +++ b/thunar/thunar-details-view.c @@ -24,8 +24,8 @@ #include <gdk/gdkkeysyms.h> #include <thunar/thunar-details-view.h> -#include <thunar/thunar-details-view-icon-renderer.h> -#include <thunar/thunar-details-view-text-renderer.h> +#include <thunar/thunar-icon-renderer.h> +#include <thunar/thunar-text-renderer.h> @@ -114,12 +114,12 @@ thunar_details_view_init (ThunarDetailsView *details_view) "resizable", TRUE, "title", _("Name"), NULL); - renderer = thunar_details_view_icon_renderer_new (); + renderer = thunar_icon_renderer_new (); gtk_tree_view_column_pack_start (column, renderer, FALSE); gtk_tree_view_column_set_attributes (column, renderer, "file", THUNAR_LIST_MODEL_COLUMN_FILE, NULL); - renderer = g_object_new (THUNAR_TYPE_DETAILS_VIEW_TEXT_RENDERER, + renderer = g_object_new (THUNAR_TYPE_TEXT_RENDERER, "xalign", 0.0, NULL); gtk_tree_view_column_pack_start (column, renderer, TRUE); @@ -134,7 +134,7 @@ thunar_details_view_init (ThunarDetailsView *details_view) "resizable", TRUE, "title", _("Size"), NULL); - renderer = g_object_new (THUNAR_TYPE_DETAILS_VIEW_TEXT_RENDERER, + renderer = g_object_new (THUNAR_TYPE_TEXT_RENDERER, "xalign", 1.0, NULL); gtk_tree_view_column_pack_start (column, renderer, TRUE); @@ -149,7 +149,7 @@ thunar_details_view_init (ThunarDetailsView *details_view) "resizable", TRUE, "title", _("Permissions"), NULL); - renderer = g_object_new (THUNAR_TYPE_DETAILS_VIEW_TEXT_RENDERER, + renderer = g_object_new (THUNAR_TYPE_TEXT_RENDERER, "xalign", 0.0, NULL); gtk_tree_view_column_pack_start (column, renderer, TRUE); diff --git a/thunar/thunar-icon-renderer.c b/thunar/thunar-icon-renderer.c new file mode 100644 index 0000000000000000000000000000000000000000..1c5115e5a72019ec7efe4f357da721204019736f --- /dev/null +++ b/thunar/thunar-icon-renderer.c @@ -0,0 +1,407 @@ +/* $Id$ */ +/*- + * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <thunar/thunar-file.h> +#include <thunar/thunar-icon-factory.h> +#include <thunar/thunar-icon-renderer.h> +#include <thunarx/thunarx-gdk-pixbuf-extensions.h> + + + +enum +{ + PROP_0, + PROP_FILE, + PROP_FOLLOW_STATE, + PROP_SIZE, +}; + + + +static void thunar_icon_renderer_class_init (ThunarIconRendererClass *klass); +static void thunar_icon_renderer_init (ThunarIconRenderer *icon_renderer); +static void thunar_icon_renderer_finalize (GObject *object); +static void thunar_icon_renderer_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void thunar_icon_renderer_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void thunar_icon_renderer_get_size (GtkCellRenderer *renderer, + GtkWidget *widget, + GdkRectangle *rectangle, + gint *x_offset, + gint *y_offset, + gint *width, + gint *height); +static void thunar_icon_renderer_render (GtkCellRenderer *renderer, + GdkWindow *window, + GtkWidget *widget, + GdkRectangle *background_area, + GdkRectangle *cell_area, + GdkRectangle *expose_area, + GtkCellRendererState flags); + + + +struct _ThunarIconRendererClass +{ + GtkCellRendererClass __parent__; +}; + +struct _ThunarIconRenderer +{ + GtkCellRenderer __parent__; + + ThunarFile *file; + gboolean follow_state; + gint size; +}; + + + +G_DEFINE_TYPE (ThunarIconRenderer, thunar_icon_renderer, GTK_TYPE_CELL_RENDERER); + + + +static void +thunar_icon_renderer_class_init (ThunarIconRendererClass *klass) +{ + GtkCellRendererClass *gtkcell_renderer_class; + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = thunar_icon_renderer_finalize; + gobject_class->get_property = thunar_icon_renderer_get_property; + gobject_class->set_property = thunar_icon_renderer_set_property; + + gtkcell_renderer_class = GTK_CELL_RENDERER_CLASS (klass); + gtkcell_renderer_class->get_size = thunar_icon_renderer_get_size; + gtkcell_renderer_class->render = thunar_icon_renderer_render; + + /** + * ThunarIconRenderer:file: + * + * The file whose icon to render. + **/ + g_object_class_install_property (gobject_class, + PROP_FILE, + g_param_spec_object ("file", + _("File"), + _("The file whose icon to render"), + THUNAR_TYPE_FILE, + EXO_PARAM_READWRITE)); + + /** + * ThunarIconRenderer::follow-state: + * + * Specifies whether the icon renderer should render icons + * based on the selection state of the items. This is necessary + * for #ExoIconView, which doesn't draw any item state indicators + * itself. + **/ + g_object_class_install_property (gobject_class, + PROP_FOLLOW_STATE, + g_param_spec_boolean ("follow-state", + _("Follow state"), + _("Follow state"), + FALSE, + EXO_PARAM_READWRITE)); + + /** + * ThunarIconRenderer:icon-size: + * + * The icon size in pixels. + **/ + g_object_class_install_property (gobject_class, + PROP_SIZE, + g_param_spec_int ("size", + _("Icon size"), + _("The icon size in pixels"), + 1, G_MAXINT, 24, + EXO_PARAM_READWRITE)); +} + + + +static void +thunar_icon_renderer_init (ThunarIconRenderer *icon_renderer) +{ + icon_renderer->size = 24; +} + + + +static void +thunar_icon_renderer_finalize (GObject *object) +{ + ThunarIconRenderer *icon_renderer = THUNAR_ICON_RENDERER (object); + + /* free the icon data */ + if (G_LIKELY (icon_renderer->file != NULL)) + g_object_unref (G_OBJECT (icon_renderer->file)); + + G_OBJECT_CLASS (thunar_icon_renderer_parent_class)->finalize (object); +} + + + +static void +thunar_icon_renderer_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + ThunarIconRenderer *icon_renderer = THUNAR_ICON_RENDERER (object); + + switch (prop_id) + { + case PROP_FILE: + g_value_set_object (value, icon_renderer->file); + break; + + case PROP_FOLLOW_STATE: + g_value_set_boolean (value, icon_renderer->follow_state); + break; + + case PROP_SIZE: + g_value_set_int (value, icon_renderer->size); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + + +static void +thunar_icon_renderer_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + ThunarIconRenderer *icon_renderer = THUNAR_ICON_RENDERER (object); + + switch (prop_id) + { + case PROP_FILE: + if (G_LIKELY (icon_renderer->file != NULL)) + g_object_unref (G_OBJECT (icon_renderer->file)); + icon_renderer->file = g_value_get_object (value); + if (G_LIKELY (icon_renderer->file != NULL)) + g_object_ref (G_OBJECT (icon_renderer->file)); + break; + + case PROP_FOLLOW_STATE: + icon_renderer->follow_state = g_value_get_boolean (value); + break; + + case PROP_SIZE: + icon_renderer->size = g_value_get_int (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + + + +static void +thunar_icon_renderer_get_size (GtkCellRenderer *renderer, + GtkWidget *widget, + GdkRectangle *rectangle, + gint *x_offset, + gint *y_offset, + gint *width, + gint *height) +{ + ThunarIconRenderer *icon_renderer = THUNAR_ICON_RENDERER (renderer); + + if (rectangle != NULL) + { + if (x_offset != NULL) + { + *x_offset = ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ? 1.0 - renderer->xalign : renderer->xalign) + * (rectangle->width - icon_renderer->size); + *x_offset = MAX (*x_offset, 0) + renderer->xpad; + } + + if (y_offset != NULL) + { + *y_offset = renderer->yalign * (rectangle->height - icon_renderer->size); + *y_offset = MAX (*y_offset, 0) + renderer->ypad; + } + } + else + { + if (x_offset != NULL) + *x_offset = 0; + + if (y_offset != NULL) + *y_offset = 0; + } + + if (G_LIKELY (width != NULL)) + *width = (gint) renderer->xpad * 2 + icon_renderer->size; + + if (G_LIKELY (height != NULL)) + *height = (gint) renderer->ypad * 2 + icon_renderer->size; +} + + + +static void +thunar_icon_renderer_render (GtkCellRenderer *renderer, + GdkWindow *window, + GtkWidget *widget, + GdkRectangle *background_area, + GdkRectangle *cell_area, + GdkRectangle *expose_area, + GtkCellRendererState flags) +{ + ThunarIconRenderer *icon_renderer = THUNAR_ICON_RENDERER (renderer); + ThunarIconFactory *icon_factory; + GdkRectangle icon_area; + GdkRectangle draw_area; + GtkStateType state; + GdkPixbuf *temp; + GdkPixbuf *icon; + GList *emblems; + GList *lp; + + if (G_UNLIKELY (icon_renderer->file == NULL)) + return; + + /* load the main icon */ + icon_factory = thunar_icon_factory_get_default (); + icon = thunar_file_load_icon (icon_renderer->file, icon_factory, icon_renderer->size); + if (G_UNLIKELY (icon == NULL)) + return; + + icon_area.width = gdk_pixbuf_get_width (icon); + icon_area.height = gdk_pixbuf_get_height (icon); + + /* scale down the icon on-demand */ + if (G_UNLIKELY (icon_area.width > icon_renderer->size || icon_area.height > icon_renderer->size)) + { + temp = exo_gdk_pixbuf_scale_ratio (icon, icon_renderer->size); + g_object_unref (G_OBJECT (icon)); + icon = temp; + + icon_area.width = gdk_pixbuf_get_width (icon); + icon_area.height = gdk_pixbuf_get_height (icon); + } + + /* colorize the icon if we should follow the selection state */ + if ((flags & (GTK_CELL_RENDERER_SELECTED | GTK_CELL_RENDERER_PRELIT)) != 0 && icon_renderer->follow_state) + { + if ((flags & GTK_CELL_RENDERER_SELECTED) != 0) + { + state = GTK_WIDGET_HAS_FOCUS (widget) ? GTK_STATE_SELECTED : GTK_STATE_ACTIVE; + temp = thunarx_gdk_pixbuf_colorize (icon, &widget->style->base[state]); + g_object_unref (G_OBJECT (icon)); + icon = temp; + } + + if ((flags & GTK_CELL_RENDERER_PRELIT) != 0) + { + temp = thunarx_gdk_pixbuf_spotlight (icon); + g_object_unref (G_OBJECT (icon)); + icon = temp; + } + } + + icon_area.x = cell_area->x + (cell_area->width - icon_area.width) / 2; + icon_area.y = cell_area->y + (cell_area->height - icon_area.height) / 2; + + if (gdk_rectangle_intersect (cell_area, &icon_area, &draw_area) + && gdk_rectangle_intersect (expose_area, &icon_area, &draw_area)) + { + gdk_draw_pixbuf (window, widget->style->black_gc, icon, + draw_area.x - icon_area.x, draw_area.y - icon_area.y, + draw_area.x, draw_area.y, draw_area.width, draw_area.height, + GDK_RGB_DITHER_NORMAL, 0, 0); + } + + g_object_unref (G_OBJECT (icon)); + + /* display the primary emblem as well (if any) */ + emblems = thunar_file_get_emblem_names (icon_renderer->file); + if (emblems != NULL) + { + /* lookup the first emblem icon that exits in the icon theme */ + for (icon = NULL, lp = emblems; lp != NULL; lp = lp->next) + { + icon = thunar_icon_factory_load_icon (icon_factory, lp->data, icon_renderer->size, NULL, FALSE); + if (G_LIKELY (icon != NULL)) + break; + } + + if (G_LIKELY (icon != NULL)) + { + icon_area.width = gdk_pixbuf_get_width (icon); + icon_area.height = gdk_pixbuf_get_height (icon); + icon_area.x = cell_area->x + (cell_area->width - renderer->xpad ) / 2; + icon_area.y = cell_area->y + (cell_area->height - renderer->ypad) / 2; + + if (gdk_rectangle_intersect (expose_area, &icon_area, &draw_area)) + { + gdk_draw_pixbuf (window, widget->style->black_gc, icon, + draw_area.x - icon_area.x, draw_area.y - icon_area.y, + draw_area.x, draw_area.y, draw_area.width, draw_area.height, + GDK_RGB_DITHER_NORMAL, 0, 0); + } + + g_object_unref (G_OBJECT (icon)); + } + + g_list_free (emblems); + } +} + + + +/** + * thunar_icon_renderer_new: + * + * Creates a new #ThunarIconRenderer. Adjust rendering + * parameters using object properties. Object properties can be + * set globally with #g_object_set. Also, with #GtkTreeViewColumn, + * you can bind a property to a value in a #GtkTreeModel. + * + * Return value: the newly allocated #ThunarIconRenderer. + **/ +GtkCellRenderer* +thunar_icon_renderer_new (void) +{ + return g_object_new (THUNAR_TYPE_ICON_RENDERER, NULL); +} + + diff --git a/thunar/thunar-icon-renderer.h b/thunar/thunar-icon-renderer.h new file mode 100644 index 0000000000000000000000000000000000000000..cab83c39c7d11aa3a588b3be34eac128433c8a49 --- /dev/null +++ b/thunar/thunar-icon-renderer.h @@ -0,0 +1,43 @@ +/* $Id$ */ +/*- + * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __THUNAR_ICON_RENDERER_H__ +#define __THUNAR_ICON_RENDERER_H__ + +#include <gtk/gtk.h> + +G_BEGIN_DECLS; + +typedef struct _ThunarIconRendererClass ThunarIconRendererClass; +typedef struct _ThunarIconRenderer ThunarIconRenderer; + +#define THUNAR_TYPE_ICON_RENDERER (thunar_icon_renderer_get_type ()) +#define THUNAR_ICON_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_ICON_RENDERER, ThunarIconRenderer)) +#define THUNAR_ICON_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_ICON_RENDERER, ThunarIconRendererClass)) +#define THUNAR_IS_ICON_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_ICON_RENDERER)) +#define THUNAR_IS_ICON_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_ICON_RENDERER)) +#define THUNAR_ICON_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_ICON_RENDERER, ThunarIconRendererClass)) + +GType thunar_icon_renderer_get_type (void) G_GNUC_CONST; + +GtkCellRenderer *thunar_icon_renderer_new (void) G_GNUC_MALLOC; + +G_END_DECLS; + +#endif /* !__THUNAR_ICON_RENDERER_H__ */ diff --git a/thunar/thunar-icon-view.c b/thunar/thunar-icon-view.c index 60a9f4dbef3b715613e66d8fcfbcf5479e3f5e34..93ee70cb155220f9963f888a7dffcb4b2e4241e4 100644 --- a/thunar/thunar-icon-view.c +++ b/thunar/thunar-icon-view.c @@ -21,7 +21,11 @@ #include <config.h> #endif +#include <gdk/gdkkeysyms.h> + +#include <thunar/thunar-icon-renderer.h> #include <thunar/thunar-icon-view.h> +#include <thunar/thunar-text-renderer.h> @@ -33,6 +37,12 @@ static void thunar_icon_view_select_all (ThunarStandardView *stan static void thunar_icon_view_unselect_all (ThunarStandardView *standard_view); static void thunar_icon_view_select_path (ThunarStandardView *standard_view, GtkTreePath *path); +static gboolean thunar_icon_view_button_press_event (ExoIconView *view, + GdkEventButton *event, + ThunarIconView *icon_view); +static gboolean thunar_icon_view_key_press_event (ExoIconView *view, + GdkEventKey *event, + ThunarIconView *icon_view); static void thunar_icon_view_item_activated (ExoIconView *view, GtkTreePath *path, ThunarIconView *icon_view); @@ -76,21 +86,38 @@ thunar_icon_view_class_init (ThunarIconViewClass *klass) static void thunar_icon_view_init (ThunarIconView *icon_view) { - GtkWidget *view; + GtkCellRenderer *renderer; + GtkWidget *view; /* create the real view */ view = exo_icon_view_new (); - g_signal_connect (G_OBJECT (view), "item-activated", - G_CALLBACK (thunar_icon_view_item_activated), icon_view); - g_signal_connect_swapped (G_OBJECT (view), "selection-changed", - G_CALLBACK (thunar_standard_view_selection_changed), icon_view); + g_signal_connect (G_OBJECT (view), "button-press-event", G_CALLBACK (thunar_icon_view_button_press_event), icon_view); + g_signal_connect (G_OBJECT (view), "key-press-event", G_CALLBACK (thunar_icon_view_key_press_event), icon_view); + g_signal_connect (G_OBJECT (view), "item-activated", G_CALLBACK (thunar_icon_view_item_activated), icon_view); + g_signal_connect_swapped (G_OBJECT (view), "selection-changed", G_CALLBACK (thunar_standard_view_selection_changed), icon_view); gtk_container_add (GTK_CONTAINER (icon_view), view); gtk_widget_show (view); /* initialize the icon view properties */ - exo_icon_view_set_text_column (EXO_ICON_VIEW (view), THUNAR_LIST_MODEL_COLUMN_NAME); - exo_icon_view_set_pixbuf_column (EXO_ICON_VIEW (view), THUNAR_LIST_MODEL_COLUMN_ICON_NORMAL); exo_icon_view_set_selection_mode (EXO_ICON_VIEW (view), GTK_SELECTION_MULTIPLE); + + /* add the icon renderer */ + renderer = g_object_new (THUNAR_TYPE_ICON_RENDERER, + "follow-state", TRUE, + "size", 48, + NULL); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (view), renderer, FALSE); + gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (view), renderer, "file", THUNAR_LIST_MODEL_COLUMN_FILE); + + /* add the text renderer */ + renderer = g_object_new (THUNAR_TYPE_TEXT_RENDERER, + "follow-state", TRUE, + "wrap-mode", PANGO_WRAP_WORD_CHAR, + "wrap-width", 128, + "yalign", 0.0f, + NULL); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (view), renderer, TRUE); + gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (view), renderer, "text", THUNAR_LIST_MODEL_COLUMN_NAME); } @@ -151,6 +178,55 @@ thunar_icon_view_select_path (ThunarStandardView *standard_view, +static gboolean +thunar_icon_view_button_press_event (ExoIconView *view, + GdkEventButton *event, + ThunarIconView *icon_view) +{ + GtkTreePath *path; + + /* open the context menu on right clicks */ + if (event->type == GDK_BUTTON_PRESS && event->button == 3 + && exo_icon_view_get_item_at_pos (view, event->x, event->y, &path, NULL)) + { + /* select the path on which the user clicked if not selected yet */ + if (!exo_icon_view_path_is_selected (view, path)) + { + /* we don't unselect all other items if Control is active */ + if ((event->state & GDK_CONTROL_MASK) == 0) + exo_icon_view_unselect_all (view); + exo_icon_view_select_path (view, path); + } + gtk_tree_path_free (path); + + /* open the context menu */ + thunar_standard_view_context_menu (THUNAR_STANDARD_VIEW (icon_view), event->button, event->time); + + return TRUE; + } + + return FALSE; +} + + + +static gboolean +thunar_icon_view_key_press_event (ExoIconView *view, + GdkEventKey *event, + ThunarIconView *icon_view) +{ + /* popup context menu if "Menu" or "<Shift>F10" is pressed */ + if (event->keyval == GDK_Menu || ((event->state & GDK_SHIFT_MASK) != 0 && event->keyval == GDK_F10)) + { + thunar_standard_view_context_menu (THUNAR_STANDARD_VIEW (icon_view), 0, event->time); + return TRUE; + } + + return FALSE; +} + + + static void thunar_icon_view_item_activated (ExoIconView *view, GtkTreePath *path, diff --git a/thunar/thunar-launcher.h b/thunar/thunar-launcher.h index 0113a23b262bb5c661d8dab2fb71fa96a2b757bb..375826d7d1767203ef58b1c2b5ffcbada6ca4efb 100644 --- a/thunar/thunar-launcher.h +++ b/thunar/thunar-launcher.h @@ -36,7 +36,7 @@ typedef struct _ThunarLauncher ThunarLauncher; GType thunar_launcher_get_type (void) G_GNUC_CONST; -ThunarLauncher *thunar_launcher_new (void) EXO_GNUC_MALLOC; +ThunarLauncher *thunar_launcher_new (void) G_GNUC_MALLOC; GtkActionGroup *thunar_launcher_get_action_group (const ThunarLauncher *launcher); void thunar_launcher_set_action_group (ThunarLauncher *launcher, diff --git a/thunar/thunar-open-with-action.h b/thunar/thunar-open-with-action.h index 59be169d7c4f9fe91f448a42ffc22eabeccbcb26..25ee0feb8ea0a691e39bf0ec7048692111414d4b 100644 --- a/thunar/thunar-open-with-action.h +++ b/thunar/thunar-open-with-action.h @@ -37,7 +37,7 @@ typedef struct _ThunarOpenWithAction ThunarOpenWithAction; GType thunar_open_with_action_get_type (void) G_GNUC_CONST; GtkAction *thunar_open_with_action_new (const gchar *name, - const gchar *label) EXO_GNUC_MALLOC; + const gchar *label) G_GNUC_MALLOC; ThunarFile *thunar_open_with_action_get_file (ThunarOpenWithAction *open_with_action); void thunar_open_with_action_set_file (ThunarOpenWithAction *open_with_action, diff --git a/thunar/thunar-text-renderer.c b/thunar/thunar-text-renderer.c new file mode 100644 index 0000000000000000000000000000000000000000..f99cd399171ed3d22f5eb4615ccdc3109cde1beb --- /dev/null +++ b/thunar/thunar-text-renderer.c @@ -0,0 +1,547 @@ +/* $Id$ */ +/*- + * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <exo/exo.h> + +#include <thunar/thunar-text-renderer.h> + + + +enum +{ + PROP_0, + PROP_FOLLOW_STATE, + PROP_TEXT, + PROP_WRAP_MODE, + PROP_WRAP_WIDTH, +}; + + + +static void thunar_text_renderer_class_init (ThunarTextRendererClass *klass); +static void thunar_text_renderer_init (ThunarTextRenderer *text_renderer); +static void thunar_text_renderer_finalize (GObject *object); +static void thunar_text_renderer_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void thunar_text_renderer_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void thunar_text_renderer_get_size (GtkCellRenderer *renderer, + GtkWidget *widget, + GdkRectangle *cell_area, + gint *x_offset, + gint *y_offset, + gint *width, + gint *height); +static void thunar_text_renderer_render (GtkCellRenderer *renderer, + GdkWindow *window, + GtkWidget *widget, + GdkRectangle *background_area, + GdkRectangle *cell_area, + GdkRectangle *expose_area, + GtkCellRendererState flags); +static void thunar_text_renderer_invalidate (ThunarTextRenderer *text_renderer); +static void thunar_text_renderer_set_widget (ThunarTextRenderer *text_renderer, + GtkWidget *widget); + + + +struct _ThunarTextRendererClass +{ + GtkCellRendererClass __parent__; +}; + +struct _ThunarTextRenderer +{ + GtkCellRenderer __parent__; + + PangoLayout *layout; + GtkWidget *widget; + gchar text[256]; + gint char_width; + gint char_height; + PangoWrapMode wrap_mode; + gint wrap_width; + gboolean follow_state; +}; + + + +G_DEFINE_TYPE (ThunarTextRenderer, thunar_text_renderer, GTK_TYPE_CELL_RENDERER); + + + +static void +thunar_text_renderer_class_init (ThunarTextRendererClass *klass) +{ + GtkCellRendererClass *gtkcell_renderer_class; + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = thunar_text_renderer_finalize; + gobject_class->get_property = thunar_text_renderer_get_property; + gobject_class->set_property = thunar_text_renderer_set_property; + + gtkcell_renderer_class = GTK_CELL_RENDERER_CLASS (klass); + gtkcell_renderer_class->get_size = thunar_text_renderer_get_size; + gtkcell_renderer_class->render = thunar_text_renderer_render; + + /** + * ThunarTextRenderer:follow-state: + * + * Specifies whether the text renderer should render text + * based on the selection state of the items. This is necessary + * for #ExoIconView, which doesn't draw any item state indicators + * itself. + **/ + g_object_class_install_property (gobject_class, + PROP_FOLLOW_STATE, + g_param_spec_boolean ("follow-state", + _("Follow state"), + _("Follow state"), + FALSE, + EXO_PARAM_READWRITE)); + + /** + * ThunarTextRenderer:text: + * + * The text to render. + **/ + g_object_class_install_property (gobject_class, + PROP_TEXT, + g_param_spec_string ("text", + _("Text"), + _("The text to render"), + NULL, + EXO_PARAM_READWRITE)); + + /** + * ThunarTextRenderer:wrap-mode: + * + * Specifies how to break the string into multiple lines, if the cell renderer + * does not have enough room to display the entire string. This property has + * no effect unless the wrap-width property is set. + **/ + g_object_class_install_property (gobject_class, + PROP_WRAP_MODE, + g_param_spec_enum ("wrap-mode", + _("Wrap mode"), + _("The wrap mode"), + PANGO_TYPE_WRAP_MODE, + PANGO_WRAP_CHAR, + EXO_PARAM_READWRITE)); + + /** + * ThunarTextRenderer:wrap-width: + * + * Specifies the width at which the text is wrapped. The wrap-mode property can + * be used to influence at what character positions the line breaks can be placed. + * Setting wrap-width to -1 turns wrapping off. + **/ + g_object_class_install_property (gobject_class, + PROP_WRAP_WIDTH, + g_param_spec_int ("wrap-width", + _("Wrap width"), + _("The wrap width"), + -1, G_MAXINT, -1, + EXO_PARAM_READWRITE)); +} + + + +static void +thunar_text_renderer_init (ThunarTextRenderer *text_renderer) +{ + text_renderer->wrap_width = -1; +} + + + +static void +thunar_text_renderer_finalize (GObject *object) +{ + ThunarTextRenderer *text_renderer = THUNAR_TEXT_RENDERER (object); + + /* drop the cached widget */ + thunar_text_renderer_set_widget (text_renderer, NULL); + + G_OBJECT_CLASS (thunar_text_renderer_parent_class)->finalize (object); +} + + + +static void +thunar_text_renderer_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + ThunarTextRenderer *text_renderer = THUNAR_TEXT_RENDERER (object); + + switch (prop_id) + { + case PROP_FOLLOW_STATE: + g_value_set_boolean (value, text_renderer->follow_state); + break; + + case PROP_TEXT: + g_value_set_string (value, text_renderer->text); + break; + + case PROP_WRAP_MODE: + g_value_set_enum (value, text_renderer->wrap_mode); + break; + + case PROP_WRAP_WIDTH: + g_value_set_int (value, text_renderer->wrap_width); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + + +static void +thunar_text_renderer_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + ThunarTextRenderer *text_renderer = THUNAR_TEXT_RENDERER (object); + const gchar *sval; + + switch (prop_id) + { + case PROP_FOLLOW_STATE: + text_renderer->follow_state = g_value_get_boolean (value); + break; + + case PROP_TEXT: + sval = g_value_get_string (value); + g_strlcpy (text_renderer->text, G_UNLIKELY (sval == NULL) ? "" : sval, sizeof (text_renderer->text)); + break; + + case PROP_WRAP_MODE: + text_renderer->wrap_mode = g_value_get_enum (value); + break; + + case PROP_WRAP_WIDTH: + text_renderer->wrap_width = g_value_get_int (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + + +static void +thunar_text_renderer_get_size (GtkCellRenderer *renderer, + GtkWidget *widget, + GdkRectangle *cell_area, + gint *x_offset, + gint *y_offset, + gint *width, + gint *height) +{ + ThunarTextRenderer *text_renderer = THUNAR_TEXT_RENDERER (renderer); + gint text_length; + gint text_width; + gint text_height; + gint focus_padding; + gint focus_width; + + /* setup the new widget */ + thunar_text_renderer_set_widget (text_renderer, widget); + + /* we can guess the dimensions if we don't wrap */ + if (text_renderer->wrap_width < 0) + { + /* determine the text_length in characters */ + text_length = g_utf8_strlen (text_renderer->text, -1); + + /* calculate the appromixate text width/height */ + text_width = text_renderer->char_width * text_length; + text_height = text_renderer->char_height; + } + else + { + /* calculate the real text dimension */ + pango_layout_set_width (text_renderer->layout, text_renderer->wrap_width * PANGO_SCALE); + pango_layout_set_wrap (text_renderer->layout, text_renderer->wrap_mode); + pango_layout_set_text (text_renderer->layout, text_renderer->text, -1); + pango_layout_get_pixel_size (text_renderer->layout, &text_width, &text_height); + } + + /* if we have to follow the state manually, we'll need + * to reserve some space to render the indicator to. + */ + if (text_renderer->follow_state) + { + gtk_widget_style_get (widget, "focus-padding", &focus_padding, "focus-line-width", &focus_width, NULL); + text_width += 2 * (focus_padding + focus_width); + text_height += 2 * (focus_padding + focus_width); + } + + /* update width/height */ + if (G_LIKELY (width != NULL)) + *width = text_width + 2 * renderer->xpad; + if (G_LIKELY (height != NULL)) + *height = text_height + 2 * renderer->ypad; + + /* update the x/y offsets */ + if (G_LIKELY (cell_area != NULL)) + { + if (G_LIKELY (x_offset != NULL)) + { + *x_offset = ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ? (1.0 - renderer->xalign) : renderer->xalign) + * (cell_area->width - text_width - (2 * renderer->xpad)); + *x_offset = MAX (*x_offset, 0); + } + + if (G_LIKELY (y_offset != NULL)) + { + *y_offset = renderer->yalign * (cell_area->height - text_height - (2 * renderer->ypad)); + *y_offset = MAX (*y_offset, 0); + } + } +} + + + +static void +thunar_text_renderer_render (GtkCellRenderer *renderer, + GdkWindow *window, + GtkWidget *widget, + GdkRectangle *background_area, + GdkRectangle *cell_area, + GdkRectangle *expose_area, + GtkCellRendererState flags) +{ + ThunarTextRenderer *text_renderer = THUNAR_TEXT_RENDERER (renderer); + GtkStateType state; +#if !GTK_CHECK_VERSION(2,8,0) + GdkPoint points[8]; +#else + cairo_t *cr; +#endif + gint x0, x1, y0, y1; + gint focus_padding; + gint focus_width; + gint text_width; + gint text_height; + gint x_offset; + gint y_offset; + + /* setup the new widget */ + thunar_text_renderer_set_widget (text_renderer, widget); + + if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED) + { + if (GTK_WIDGET_HAS_FOCUS (widget)) + state = GTK_STATE_SELECTED; + else + state = GTK_STATE_ACTIVE; + } + else if ((flags & GTK_CELL_RENDERER_PRELIT) == GTK_CELL_RENDERER_PRELIT + && GTK_WIDGET_STATE (widget) == GTK_STATE_PRELIGHT) + { + state = GTK_STATE_PRELIGHT; + } + else + { + if (GTK_WIDGET_STATE (widget) == GTK_STATE_INSENSITIVE) + state = GTK_STATE_INSENSITIVE; + else + state = GTK_STATE_NORMAL; + } + + /* setup the wrapping */ + if (text_renderer->wrap_width < 0) + { + pango_layout_set_width (text_renderer->layout, -1); + pango_layout_set_wrap (text_renderer->layout, PANGO_WRAP_CHAR); + } + else + { + pango_layout_set_width (text_renderer->layout, text_renderer->wrap_width * PANGO_SCALE); + pango_layout_set_wrap (text_renderer->layout, text_renderer->wrap_mode); + } + + pango_layout_set_text (text_renderer->layout, text_renderer->text, -1); + + /* calculate the real text dimension */ + pango_layout_get_pixel_size (text_renderer->layout, &text_width, &text_height); + + /* take into account the state indicator (required for calculation) */ + if (text_renderer->follow_state) + { + gtk_widget_style_get (widget, "focus-padding", &focus_padding, "focus-line-width", &focus_width, NULL); + text_width += 2 * (focus_padding + focus_width); + text_height += 2 * (focus_padding + focus_width); + } + + /* calculate the real x-offset */ + x_offset = ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ? (1.0 - renderer->xalign) : renderer->xalign) + * (cell_area->width - text_width - (2 * renderer->xpad)); + x_offset = MAX (x_offset, 0); + + /* calculate the real y-offset */ + y_offset = renderer->yalign * (cell_area->height - text_height - (2 * renderer->ypad)); + y_offset = MAX (y_offset, 0); + + /* render the state indicator */ + if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED && text_renderer->follow_state) + { + /* calculate the text bounding box (including the focus padding/width) */ + x0 = cell_area->x + x_offset; + y0 = cell_area->y + y_offset; + x1 = x0 + text_width; + y1 = y0 + text_height; + +#if GTK_CHECK_VERSION(2,8,0) + /* Cairo produces nicer results than using a polygon + * and so we use it directly if possible. + */ + cr = gdk_cairo_create (window); + cairo_move_to (cr, x0 + 5, y0); + cairo_line_to (cr, x1 - 5, y0); + cairo_curve_to (cr, x1 - 5, y0, x1, y0, x1, y0 + 5); + cairo_line_to (cr, x1, y1 - 5); + cairo_curve_to (cr, x1, y1 - 5, x1, y1, x1 - 5, y1); + cairo_line_to (cr, x0 + 5, y1); + cairo_curve_to (cr, x0 + 5, y1, x0, y1, x0, y1 - 5); + cairo_line_to (cr, x0, y0 + 5); + cairo_curve_to (cr, x0, y0 + 5, x0, y0, x0 + 5, y0); + gdk_cairo_set_source_color (cr, &widget->style->base[state]); + cairo_fill (cr); + cairo_destroy (cr); +#else + /* calculate a (more or less rounded) polygon */ + points[0].x = x0 + 2; points[0].y = y0; + points[1].x = x1 - 2; points[1].y = y0; + points[2].x = x1; points[2].y = y0 + 2; + points[3].x = x1; points[3].y = y1 - 2; + points[4].x = x1 - 2; points[4].y = y1; + points[5].x = x0 + 2; points[5].y = y1; + points[6].x = x0; points[6].y = y1 - 2; + points[7].x = x0; points[7].y = y0 + 2; + + /* render the indicator */ + gdk_draw_polygon (window, widget->style->base_gc[state], TRUE, points, G_N_ELEMENTS (points)); +#endif + } + + /* get proper sizing for the layout drawing */ + if (text_renderer->follow_state) + { + text_width -= 2 * (focus_padding + focus_width); + text_height -= 2 * (focus_padding + focus_width); + x_offset += focus_padding + focus_width; + y_offset += focus_padding + focus_width; + } + + /* draw the text */ + gtk_paint_layout (widget->style, window, state, TRUE, + expose_area, widget, "cellrenderertext", + cell_area->x + x_offset + renderer->xpad, + cell_area->y + y_offset + renderer->ypad, + text_renderer->layout); +} + + + +static void +thunar_text_renderer_invalidate (ThunarTextRenderer *text_renderer) +{ + thunar_text_renderer_set_widget (text_renderer, NULL); +} + + + +static void +thunar_text_renderer_set_widget (ThunarTextRenderer *text_renderer, + GtkWidget *widget) +{ + // FIXME: The sample text should be translatable with a hint to translators! + static const gchar SAMPLE_TEXT[] = "The Quick Brown Fox Jumps Over the Lazy Dog"; + PangoRectangle extents; + + if (G_LIKELY (widget == text_renderer->widget)) + return; + + /* disconnect from the previously set widget */ + if (G_UNLIKELY (text_renderer->widget != NULL)) + { + g_signal_handlers_disconnect_by_func (G_OBJECT (text_renderer->widget), thunar_text_renderer_invalidate, text_renderer); + g_object_unref (G_OBJECT (text_renderer->layout)); + g_object_unref (G_OBJECT (text_renderer->widget)); + } + + /* activate the new widget */ + text_renderer->widget = widget; + + /* connect to the new widget */ + if (G_LIKELY (widget != NULL)) + { + /* take a reference on the widget */ + g_object_ref (G_OBJECT (widget)); + + /* we need to recalculate the metrics when a new style (and thereby a new font) is set */ + g_signal_connect_swapped (G_OBJECT (text_renderer->widget), "destroy", G_CALLBACK (thunar_text_renderer_invalidate), text_renderer); + g_signal_connect_swapped (G_OBJECT (text_renderer->widget), "style-set", G_CALLBACK (thunar_text_renderer_invalidate), text_renderer); + + /* calculate the average character dimensions */ + text_renderer->layout = gtk_widget_create_pango_layout (widget, SAMPLE_TEXT); + pango_layout_get_pixel_extents (text_renderer->layout, NULL, &extents); + pango_layout_set_width (text_renderer->layout, -1); + text_renderer->char_width = extents.width / g_utf8_strlen (SAMPLE_TEXT, sizeof (SAMPLE_TEXT) - 1); + text_renderer->char_height = extents.height; + } + else + { + text_renderer->layout = NULL; + text_renderer->char_width = 0; + text_renderer->char_height = 0; + } +} + + + +/** + * thunar_text_renderer_new: + **/ +GtkCellRenderer* +thunar_text_renderer_new (void) +{ + return g_object_new (THUNAR_TYPE_TEXT_RENDERER, NULL); +} + diff --git a/thunar/thunar-text-renderer.h b/thunar/thunar-text-renderer.h new file mode 100644 index 0000000000000000000000000000000000000000..8f4776125224d00808fac7698a73bbf4aa8b9565 --- /dev/null +++ b/thunar/thunar-text-renderer.h @@ -0,0 +1,43 @@ +/* $Id$ */ +/*- + * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __THUNAR_TEXT_RENDERER_H__ +#define __THUNAR_TEXT_RENDERER_H__ + +#include <gtk/gtk.h> + +G_BEGIN_DECLS; + +typedef struct _ThunarTextRendererClass ThunarTextRendererClass; +typedef struct _ThunarTextRenderer ThunarTextRenderer; + +#define THUNAR_TYPE_TEXT_RENDERER (thunar_text_renderer_get_type ()) +#define THUNAR_TEXT_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_TEXT_RENDERER, ThunarTextRenderer)) +#define THUNAR_TEXT_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_TEXT_RENDERER, ThunarTextRendererClass)) +#define THUNAR_IS_TEXT_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_TEXT_RENDERER)) +#define THUNAR_IS_TEXT_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_TEXT_RENDERER)) +#define THUNAR_TEXT_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_TEXT_RENDERER, ThunarTextRendererClass)) + +GType thunar_text_renderer_get_type (void) G_GNUC_CONST; + +GtkCellRenderer *thunar_text_renderer_new (void) G_GNUC_MALLOC; + +G_END_DECLS; + +#endif /* !__THUNAR_TEXT_RENDERER_H__ */ diff --git a/thunar/thunar-window.c b/thunar/thunar-window.c index 53e931bcbc3eab7cd78bb1625f0a040f07c25136..e8492088d7a6e32c3500a3dcdda928a1a7188120 100644 --- a/thunar/thunar-window.c +++ b/thunar/thunar-window.c @@ -244,7 +244,7 @@ thunar_window_init (ThunarWindow *window) gtk_box_pack_start (GTK_BOX (box), window->location_bar, FALSE, FALSE, 0); gtk_widget_show (window->location_bar); - window->view = thunar_details_view_new (); + window->view = thunar_icon_view_new (); g_signal_connect (G_OBJECT (window->view), "notify::loading", G_CALLBACK (thunar_window_notify_loading), window); g_signal_connect_swapped (G_OBJECT (window->view), "change-directory", @@ -450,20 +450,39 @@ static void thunar_window_action_about (GtkAction *action, ThunarWindow *window) { - XfceAboutInfo *info; - GtkWidget *dialog; - - info = xfce_about_info_new (PACKAGE_NAME, PACKAGE_VERSION, _("File Manager"), - XFCE_COPYRIGHT_TEXT ("2004-2005", "Benedikt Meurer"), - XFCE_LICENSE_GPL); - xfce_about_info_set_homepage (info, "http://thunar.xfce.org/"); - xfce_about_info_add_credit (info, "Benedikt Meurer", "benny@xfce.org", _("Project leader")); - - dialog = xfce_about_dialog_new (GTK_WINDOW (window), info, NULL); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - - xfce_about_info_free (info); + static const gchar *authors[] = + { + "Benedikt Meurer <benny@xfce.org>", + NULL, + }; + + static const gchar license[] = + "This program is free software; you can redistribute it and/or modify it\n" + "under the terms of the GNU General Public License as published by the Free\n" + "Software Foundation; either version 2 of the License, or (at your option)\n" + "any later version.\n" + "\n" + "This program is distributed in the hope that it will be useful, but WITHOUT\n" + "ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n" + "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\n" + "more details.\n" + "\n" + "You should have received a copy of the GNU General Public License along with\n" + "this program; if not, write to the Free Software Foundation, Inc., 59 Temple\n" + "Place, Suite 330, Boston, MA 02111-1307 USA.\n"; + + gtk_about_dialog_set_email_hook ((gpointer) exo_noop, NULL, NULL); + gtk_about_dialog_set_url_hook ((gpointer) exo_noop, NULL, NULL); + gtk_show_about_dialog (GTK_WINDOW (window), + "authors", authors, + "comments", _("Thunar is a fast and easy to use file manager\nfor the Xfce Desktop Environment."), + "copyright", "Copyright © 2004-2005 Benedikt Meurer", + "license", license, + "name", PACKAGE_NAME, + "translator-credits", _("translator-credits"), + "version", PACKAGE_VERSION, + "website", "http://thunar.xfce.org/", + NULL); } diff --git a/thunarx/thunarx-gdk-pixbuf-extensions.c b/thunarx/thunarx-gdk-pixbuf-extensions.c index f5d51bfd9bee984b6fbacba749db88fe51670203..8542a648440d042a74d9f5488e52cd6ac7310eac 100644 --- a/thunarx/thunarx-gdk-pixbuf-extensions.c +++ b/thunarx/thunarx-gdk-pixbuf-extensions.c @@ -15,6 +15,9 @@ * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place, Suite 330, Boston, MA 02111-1307 USA + * + * Based on code originally written by Eazel, Inc. for the eel utility + * library. */ #ifdef HAVE_CONFIG_H @@ -36,36 +39,40 @@ * Return value: the colorized #GdkPixbuf. **/ GdkPixbuf* -thunarx_gdk_pixbuf_colorize (GdkPixbuf *src, - const GdkColor *color) +thunarx_gdk_pixbuf_colorize (const GdkPixbuf *src, + const GdkColor *color) { - gint i, j; - gint width, height, has_alpha, src_row_stride, dst_row_stride; - gint red_value, green_value, blue_value; - guchar *target_pixels; - guchar *original_pixels; - guchar *pixsrc; - guchar *pixdest; GdkPixbuf *dest; + gboolean has_alpha; + guchar *original_pixels; + guchar *target_pixels; + guchar *pixdest; + guchar *pixsrc; + gint dst_row_stride; + gint src_row_stride; + gint width; + gint height; + gint red_value; + gint green_value; + gint blue_value; + gint i; + gint j; red_value = color->red / 255.0; green_value = color->green / 255.0; blue_value = color->blue / 255.0; - dest = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (src), - gdk_pixbuf_get_has_alpha (src), - gdk_pixbuf_get_bits_per_sample (src), - gdk_pixbuf_get_width (src), - gdk_pixbuf_get_height (src)); - has_alpha = gdk_pixbuf_get_has_alpha (src); width = gdk_pixbuf_get_width (src); height = gdk_pixbuf_get_height (src); src_row_stride = gdk_pixbuf_get_rowstride (src); - dst_row_stride = gdk_pixbuf_get_rowstride (dest); - target_pixels = gdk_pixbuf_get_pixels (dest); original_pixels = gdk_pixbuf_get_pixels (src); + dest = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (src), has_alpha, gdk_pixbuf_get_bits_per_sample (src), width, height); + + dst_row_stride = gdk_pixbuf_get_rowstride (dest); + target_pixels = gdk_pixbuf_get_pixels (dest); + for (i = 0; i < height; i++) { pixdest = target_pixels + i*dst_row_stride; @@ -87,4 +94,78 @@ thunarx_gdk_pixbuf_colorize (GdkPixbuf *src, +static guchar +lighten_channel (guchar cur_value) +{ + gint new_value = cur_value; + + new_value += 24 + (new_value >> 3); + if (G_UNLIKELY (new_value > 255)) + new_value = 255; + + return (guchar) new_value; +} + + + +/** + * thunarx_gdk_pixbuf_spotlight: + * @src : the source #GdkPixbuf. + * + * Creates a lightened version of @src, suitable for + * prelit state display of icons. + * + * The caller is responsible to free the returned + * pixbuf using #g_object_unref(). + * + * Return value: the lightened version of @src. + **/ +GdkPixbuf* +thunarx_gdk_pixbuf_spotlight (const GdkPixbuf *src) +{ + GdkPixbuf *dest; + gboolean has_alpha; + guchar *original_pixels; + guchar *target_pixels; + guchar *pixdest; + guchar *pixsrc; + gint dst_row_stride; + gint src_row_stride; + gint width; + gint height; + gint i; + gint j; + + has_alpha = gdk_pixbuf_get_has_alpha (src); + width = gdk_pixbuf_get_width (src); + height = gdk_pixbuf_get_height (src); + src_row_stride = gdk_pixbuf_get_rowstride (src); + original_pixels = gdk_pixbuf_get_pixels (src); + + dest = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (src), has_alpha, gdk_pixbuf_get_bits_per_sample (src), width, height); + + dst_row_stride = gdk_pixbuf_get_rowstride (dest); + target_pixels = gdk_pixbuf_get_pixels (dest); + + for (i = 0; i < height; ++i) + { + pixdest = target_pixels + i * dst_row_stride; + pixsrc = original_pixels + i * src_row_stride; + + for (j = 0; j < width; ++j) + { + *pixdest++ = lighten_channel (*pixsrc++); + *pixdest++ = lighten_channel (*pixsrc++); + *pixdest++ = lighten_channel (*pixsrc++); + + if (G_LIKELY (has_alpha)) + *pixdest++ = *pixsrc++; + } + } + + return dest; +} + + + diff --git a/thunarx/thunarx-gdk-pixbuf-extensions.h b/thunarx/thunarx-gdk-pixbuf-extensions.h index 6f685cdaaef8a78250577efc390b135ca8cadf3a..2287fc2e0160a68afa08221bcd1effa66b8ef153 100644 --- a/thunarx/thunarx-gdk-pixbuf-extensions.h +++ b/thunarx/thunarx-gdk-pixbuf-extensions.h @@ -24,8 +24,9 @@ G_BEGIN_DECLS; -GdkPixbuf *thunarx_gdk_pixbuf_colorize (GdkPixbuf *src, - const GdkColor *color); +GdkPixbuf *thunarx_gdk_pixbuf_colorize (const GdkPixbuf *src, + const GdkColor *color); +GdkPixbuf *thunarx_gdk_pixbuf_spotlight (const GdkPixbuf *src); G_END_DECLS;