Tree of tag thunar-4.20.7 (commit df0e054) from https://gitlab.xfce.org/xfce/thunar. Upstream history is not included here to keep the repository small.
755 lines
26 KiB
C
755 lines
26 KiB
C
/* vi:set et ai sw=2 sts=2 ts=2: */
|
|
/*-
|
|
* Copyright (c) 2005-2006 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-clipboard-manager.h"
|
|
#include "thunar/thunar-gdk-extensions.h"
|
|
#include "thunar/thunar-gobject-extensions.h"
|
|
#include "thunar/thunar-icon-factory.h"
|
|
#include "thunar/thunar-icon-renderer.h"
|
|
#include "thunar/thunar-private.h"
|
|
#include "thunar/thunar-util.h"
|
|
|
|
|
|
|
|
enum
|
|
{
|
|
PROP_0,
|
|
PROP_DROP_FILE,
|
|
PROP_FILE,
|
|
PROP_EMBLEMS,
|
|
PROP_FOLLOW_STATE,
|
|
PROP_SIZE,
|
|
PROP_HIGHLIGHT_COLOR,
|
|
PROP_ROUNDED_CORNERS,
|
|
PROP_HIGHLIGHTING_ENABLED,
|
|
PROP_IMAGE_PREVIEW_ENABLED,
|
|
PROP_USE_SYMBOLIC_ICONS,
|
|
};
|
|
|
|
|
|
|
|
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_preferred_width (GtkCellRenderer *renderer,
|
|
GtkWidget *widget,
|
|
gint *minimum,
|
|
gint *natural);
|
|
static void
|
|
thunar_icon_renderer_get_preferred_height (GtkCellRenderer *renderer,
|
|
GtkWidget *widget,
|
|
gint *minimum,
|
|
gint *natural);
|
|
static void
|
|
thunar_icon_renderer_render (GtkCellRenderer *renderer,
|
|
cairo_t *cr,
|
|
GtkWidget *widget,
|
|
const GdkRectangle *background_area,
|
|
const GdkRectangle *cell_area,
|
|
GtkCellRendererState flags);
|
|
|
|
|
|
|
|
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_preferred_width = thunar_icon_renderer_get_preferred_width;
|
|
gtkcell_renderer_class->get_preferred_height = thunar_icon_renderer_get_preferred_height;
|
|
gtkcell_renderer_class->render = thunar_icon_renderer_render;
|
|
|
|
/**
|
|
* ThunarIconRenderer:drop-file:
|
|
*
|
|
* The file which should be rendered in the drop
|
|
* accept state.
|
|
**/
|
|
g_object_class_install_property (gobject_class,
|
|
PROP_DROP_FILE,
|
|
g_param_spec_object ("drop-file",
|
|
"drop-file",
|
|
"drop-file",
|
|
THUNAR_TYPE_FILE,
|
|
EXO_PARAM_READWRITE));
|
|
|
|
/**
|
|
* ThunarIconRenderer:file:
|
|
*
|
|
* The file whose icon to render.
|
|
**/
|
|
g_object_class_install_property (gobject_class,
|
|
PROP_FILE,
|
|
g_param_spec_object ("file", "file", "file",
|
|
THUNAR_TYPE_FILE,
|
|
EXO_PARAM_READWRITE));
|
|
|
|
/**
|
|
* ThunarIconRenderer:emblems:
|
|
*
|
|
* Specifies whether to render emblems in addition to the file icons.
|
|
**/
|
|
g_object_class_install_property (gobject_class,
|
|
PROP_EMBLEMS,
|
|
g_param_spec_boolean ("emblems",
|
|
"emblems",
|
|
"emblems",
|
|
TRUE,
|
|
G_PARAM_CONSTRUCT | 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:size:
|
|
*
|
|
* The size at which icons should be rendered by this
|
|
* #ThunarIconRenderer instance.
|
|
**/
|
|
g_object_class_install_property (gobject_class,
|
|
PROP_SIZE,
|
|
g_param_spec_enum ("size", "size", "size",
|
|
THUNAR_TYPE_ICON_SIZE,
|
|
THUNAR_ICON_SIZE_32,
|
|
G_PARAM_CONSTRUCT | EXO_PARAM_READWRITE));
|
|
|
|
|
|
|
|
/**
|
|
* ThunarIconRenderer:highlight-color:
|
|
*
|
|
* The color with which the cell should be highlighted.
|
|
**/
|
|
g_object_class_install_property (gobject_class,
|
|
PROP_HIGHLIGHT_COLOR,
|
|
g_param_spec_string ("highlight-color", "highlight-color", "highlight-color",
|
|
NULL,
|
|
EXO_PARAM_READWRITE));
|
|
|
|
|
|
|
|
/**
|
|
* ThunarIconRenderer:rounded-corners:
|
|
*
|
|
* Determines if the cell should be clipped to rounded-corners.
|
|
* Useful when highlighting is enabled & a highlight color is set.
|
|
**/
|
|
g_object_class_install_property (gobject_class,
|
|
PROP_ROUNDED_CORNERS,
|
|
g_param_spec_boolean ("rounded-corners", "rounded-corners", "rounded-corners",
|
|
FALSE,
|
|
EXO_PARAM_READWRITE));
|
|
|
|
|
|
|
|
/**
|
|
* ThunarIconRenderer:highlighting-enabled:
|
|
*
|
|
* Determines if the cell background should be drawn with highlight color.
|
|
**/
|
|
g_object_class_install_property (gobject_class,
|
|
PROP_HIGHLIGHTING_ENABLED,
|
|
g_param_spec_boolean ("highlighting-enabled", "highlighting-enabled", "highlighting-enabled",
|
|
FALSE,
|
|
EXO_PARAM_READWRITE));
|
|
|
|
/**
|
|
* ThunarIconRenderer:image-preview-enabled:
|
|
*
|
|
* Determines if as well xxl-thumbnails should be requested
|
|
**/
|
|
g_object_class_install_property (gobject_class,
|
|
PROP_IMAGE_PREVIEW_ENABLED,
|
|
g_param_spec_boolean ("image-preview-enabled", "image-preview-enabled", "image-preview-enabled",
|
|
FALSE,
|
|
EXO_PARAM_READWRITE));
|
|
|
|
/**
|
|
* ThunarIconRenderer:use_symbolic_icons:
|
|
*
|
|
* Whether to use symbolic icons.
|
|
**/
|
|
g_object_class_install_property (gobject_class,
|
|
PROP_USE_SYMBOLIC_ICONS,
|
|
g_param_spec_boolean ("use-symbolic-icons",
|
|
"use-symbolic-icons",
|
|
"use-symbolic-icons",
|
|
FALSE,
|
|
EXO_PARAM_READWRITE));
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
thunar_icon_renderer_init (ThunarIconRenderer *icon_renderer)
|
|
{
|
|
/* use 1px padding */
|
|
gtk_cell_renderer_set_padding (GTK_CELL_RENDERER (icon_renderer), 1, 1);
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
thunar_icon_renderer_finalize (GObject *object)
|
|
{
|
|
ThunarIconRenderer *icon_renderer = THUNAR_ICON_RENDERER (object);
|
|
|
|
/* free the icon data */
|
|
if (G_UNLIKELY (icon_renderer->drop_file != NULL))
|
|
g_object_unref (G_OBJECT (icon_renderer->drop_file));
|
|
if (G_LIKELY (icon_renderer->file != NULL))
|
|
g_object_unref (G_OBJECT (icon_renderer->file));
|
|
g_free (icon_renderer->highlight_color);
|
|
|
|
(*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_DROP_FILE:
|
|
g_value_set_object (value, icon_renderer->drop_file);
|
|
break;
|
|
|
|
case PROP_FILE:
|
|
g_value_set_object (value, icon_renderer->file);
|
|
break;
|
|
|
|
case PROP_EMBLEMS:
|
|
g_value_set_boolean (value, icon_renderer->emblems);
|
|
break;
|
|
|
|
case PROP_FOLLOW_STATE:
|
|
g_value_set_boolean (value, icon_renderer->follow_state);
|
|
break;
|
|
|
|
case PROP_SIZE:
|
|
g_value_set_enum (value, icon_renderer->size);
|
|
break;
|
|
|
|
case PROP_HIGHLIGHT_COLOR:
|
|
g_value_set_string (value, icon_renderer->highlight_color);
|
|
break;
|
|
|
|
case PROP_ROUNDED_CORNERS:
|
|
g_value_set_boolean (value, icon_renderer->rounded_corners);
|
|
break;
|
|
|
|
case PROP_HIGHLIGHTING_ENABLED:
|
|
g_value_set_boolean (value, icon_renderer->highlighting_enabled);
|
|
break;
|
|
|
|
case PROP_IMAGE_PREVIEW_ENABLED:
|
|
g_value_set_boolean (value, icon_renderer->highlighting_enabled);
|
|
break;
|
|
|
|
case PROP_USE_SYMBOLIC_ICONS:
|
|
g_value_set_boolean (value, icon_renderer->use_symbolic_icons);
|
|
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_DROP_FILE:
|
|
if (G_LIKELY (icon_renderer->drop_file != NULL))
|
|
g_object_unref (G_OBJECT (icon_renderer->drop_file));
|
|
icon_renderer->drop_file = (gpointer) g_value_dup_object (value);
|
|
break;
|
|
|
|
case PROP_FILE:
|
|
if (G_LIKELY (icon_renderer->file != NULL))
|
|
g_object_unref (G_OBJECT (icon_renderer->file));
|
|
icon_renderer->file = (gpointer) g_value_dup_object (value);
|
|
break;
|
|
|
|
case PROP_EMBLEMS:
|
|
icon_renderer->emblems = g_value_get_boolean (value);
|
|
break;
|
|
|
|
case PROP_FOLLOW_STATE:
|
|
icon_renderer->follow_state = g_value_get_boolean (value);
|
|
break;
|
|
|
|
case PROP_SIZE:
|
|
icon_renderer->size = g_value_get_enum (value);
|
|
break;
|
|
|
|
case PROP_HIGHLIGHT_COLOR:
|
|
g_free (icon_renderer->highlight_color);
|
|
icon_renderer->highlight_color = g_value_dup_string (value);
|
|
break;
|
|
|
|
case PROP_ROUNDED_CORNERS:
|
|
icon_renderer->rounded_corners = g_value_get_boolean (value);
|
|
break;
|
|
|
|
case PROP_HIGHLIGHTING_ENABLED:
|
|
icon_renderer->highlighting_enabled = g_value_get_boolean (value);
|
|
break;
|
|
|
|
case PROP_IMAGE_PREVIEW_ENABLED:
|
|
icon_renderer->image_preview_enabled = g_value_get_boolean (value);
|
|
break;
|
|
|
|
case PROP_USE_SYMBOLIC_ICONS:
|
|
icon_renderer->use_symbolic_icons = g_value_get_boolean (value);
|
|
break;
|
|
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
thunar_icon_renderer_get_preferred_width (GtkCellRenderer *renderer,
|
|
GtkWidget *widget,
|
|
gint *minimum,
|
|
gint *natural)
|
|
{
|
|
ThunarIconRenderer *icon_renderer = THUNAR_ICON_RENDERER (renderer);
|
|
int xpad;
|
|
|
|
gtk_cell_renderer_get_padding (renderer, &xpad, NULL);
|
|
|
|
if (G_LIKELY (minimum))
|
|
*minimum = (gint) xpad * 2 + icon_renderer->size;
|
|
if (G_LIKELY (natural))
|
|
*natural = (gint) xpad * 2 + icon_renderer->size;
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
thunar_icon_renderer_get_preferred_height (GtkCellRenderer *renderer,
|
|
GtkWidget *widget,
|
|
gint *minimum,
|
|
gint *natural)
|
|
{
|
|
ThunarIconRenderer *icon_renderer = THUNAR_ICON_RENDERER (renderer);
|
|
int ypad;
|
|
|
|
gtk_cell_renderer_get_padding (renderer, NULL, &ypad);
|
|
|
|
if (G_LIKELY (minimum))
|
|
*minimum = (gint) ypad * 2 + icon_renderer->size;
|
|
if (G_LIKELY (natural))
|
|
*natural = (gint) ypad * 2 + icon_renderer->size;
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
thunar_icon_renderer_color_insensitive (cairo_t *cr,
|
|
GtkWidget *widget)
|
|
{
|
|
cairo_pattern_t *source;
|
|
GdkRGBA *color;
|
|
GtkStyleContext *context = gtk_widget_get_style_context (widget);
|
|
|
|
cairo_save (cr);
|
|
|
|
source = cairo_pattern_reference (cairo_get_source (cr));
|
|
gtk_style_context_get (context, GTK_STATE_FLAG_INSENSITIVE, GTK_STYLE_PROPERTY_COLOR, &color, NULL);
|
|
gdk_cairo_set_source_rgba (cr, color);
|
|
gdk_rgba_free (color);
|
|
cairo_set_operator (cr, CAIRO_OPERATOR_MULTIPLY);
|
|
|
|
cairo_mask (cr, source);
|
|
|
|
cairo_pattern_destroy (source);
|
|
cairo_restore (cr);
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
thunar_icon_renderer_color_selected (cairo_t *cr,
|
|
GtkWidget *widget)
|
|
{
|
|
cairo_pattern_t *source;
|
|
GtkStateFlags state;
|
|
GdkRGBA *color;
|
|
GtkStyleContext *context = gtk_widget_get_style_context (widget);
|
|
|
|
cairo_save (cr);
|
|
|
|
source = cairo_pattern_reference (cairo_get_source (cr));
|
|
state = gtk_widget_has_focus (widget) ? GTK_STATE_FLAG_SELECTED : GTK_STATE_FLAG_ACTIVE;
|
|
gtk_style_context_get (context, state, GTK_STYLE_PROPERTY_BACKGROUND_COLOR, &color, NULL);
|
|
gdk_cairo_set_source_rgba (cr, color);
|
|
gdk_rgba_free (color);
|
|
cairo_set_operator (cr, CAIRO_OPERATOR_MULTIPLY);
|
|
|
|
cairo_mask (cr, source);
|
|
|
|
cairo_pattern_destroy (source);
|
|
cairo_restore (cr);
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
thunar_icon_renderer_color_lighten (cairo_t *cr,
|
|
GtkWidget *widget)
|
|
{
|
|
cairo_pattern_t *source;
|
|
|
|
cairo_save (cr);
|
|
|
|
source = cairo_pattern_reference (cairo_get_source (cr));
|
|
cairo_set_source_rgb (cr, .15, .15, .15);
|
|
cairo_set_operator (cr, CAIRO_OPERATOR_COLOR_DODGE);
|
|
|
|
cairo_mask (cr, source);
|
|
|
|
cairo_pattern_destroy (source);
|
|
cairo_restore (cr);
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
thunar_icon_renderer_render (GtkCellRenderer *renderer,
|
|
cairo_t *cr,
|
|
GtkWidget *widget,
|
|
const GdkRectangle *background_area,
|
|
const GdkRectangle *cell_area,
|
|
GtkCellRendererState flags)
|
|
{
|
|
ThunarClipboardManager *clipboard;
|
|
ThunarFileIconState icon_state;
|
|
ThunarIconRenderer *icon_renderer = THUNAR_ICON_RENDERER (renderer);
|
|
ThunarIconFactory *icon_factory;
|
|
GtkIconTheme *icon_theme;
|
|
GtkStyleContext *context = NULL;
|
|
GdkRectangle emblem_area;
|
|
GdkRectangle icon_area;
|
|
GdkRectangle clip_area;
|
|
GdkPixbuf *emblem;
|
|
GdkPixbuf *icon;
|
|
GdkPixbuf *temp;
|
|
GList *emblems;
|
|
GList *lp;
|
|
gint scale_factor;
|
|
gint position;
|
|
gdouble alpha;
|
|
gint emblem_size;
|
|
gboolean color_selected;
|
|
gboolean color_lighten;
|
|
gboolean is_expanded;
|
|
|
|
if (G_UNLIKELY (icon_renderer->file == NULL))
|
|
return;
|
|
|
|
if (G_UNLIKELY (!gdk_cairo_get_clip_rectangle (cr, &clip_area)))
|
|
return;
|
|
|
|
g_object_get (renderer, "is-expanded", &is_expanded, NULL);
|
|
|
|
if (THUNAR_ICON_RENDERER (renderer)->highlighting_enabled)
|
|
thunar_util_clip_view_background (renderer, cr, background_area, widget, flags);
|
|
|
|
/* determine the icon state */
|
|
icon_state = (icon_renderer->drop_file != icon_renderer->file)
|
|
? is_expanded
|
|
? THUNAR_FILE_ICON_STATE_OPEN
|
|
: THUNAR_FILE_ICON_STATE_DEFAULT
|
|
: THUNAR_FILE_ICON_STATE_DROP;
|
|
|
|
/* load the main icon */
|
|
icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
|
|
icon_factory = thunar_icon_factory_get_for_icon_theme (icon_theme);
|
|
|
|
scale_factor = gtk_widget_get_scale_factor (widget);
|
|
|
|
/* load thumbnail for supported file type */
|
|
if (thunar_icon_factory_get_show_thumbnail (icon_factory, icon_renderer->file))
|
|
thunar_file_request_thumbnail (icon_renderer->file, thunar_icon_size_to_thumbnail_size (icon_renderer->size * scale_factor));
|
|
|
|
/* load additional thumbnail for image preview */
|
|
if (icon_renderer->image_preview_enabled)
|
|
thunar_file_request_thumbnail (icon_renderer->file, THUNAR_THUMBNAIL_SIZE_XX_LARGE);
|
|
|
|
/* get style context for symbolic icon */
|
|
if (icon_renderer->use_symbolic_icons)
|
|
context = gtk_widget_get_style_context (widget);
|
|
|
|
icon = thunar_icon_factory_load_file_icon (icon_factory, icon_renderer->file, icon_state,
|
|
icon_renderer->size, scale_factor,
|
|
icon_renderer->use_symbolic_icons, context);
|
|
if (G_UNLIKELY (icon == NULL))
|
|
{
|
|
g_object_unref (G_OBJECT (icon_factory));
|
|
return;
|
|
}
|
|
|
|
/* pre-light the item if we're dragging about it */
|
|
if (G_UNLIKELY (icon_state == THUNAR_FILE_ICON_STATE_DROP))
|
|
flags |= GTK_CELL_RENDERER_PRELIT;
|
|
|
|
/* determine the real icon size */
|
|
icon_area.width = gdk_pixbuf_get_width (icon) / scale_factor;
|
|
icon_area.height = gdk_pixbuf_get_height (icon) / scale_factor;
|
|
|
|
/* scale down the icon on-demand */
|
|
if (G_UNLIKELY (icon_area.width > cell_area->width || icon_area.height > cell_area->height))
|
|
{
|
|
/* scale down to fit */
|
|
temp = exo_gdk_pixbuf_scale_down (icon, TRUE, MAX (1, cell_area->width * scale_factor), MAX (1, cell_area->height * scale_factor));
|
|
g_object_unref (G_OBJECT (icon));
|
|
icon = temp;
|
|
|
|
/* determine the icon dimensions again */
|
|
icon_area.width = gdk_pixbuf_get_width (icon) / scale_factor;
|
|
icon_area.height = gdk_pixbuf_get_height (icon) / scale_factor;
|
|
}
|
|
|
|
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;
|
|
|
|
/* bools for cairo transformations */
|
|
color_selected = (flags & GTK_CELL_RENDERER_SELECTED) != 0 && icon_renderer->follow_state;
|
|
color_lighten = (flags & GTK_CELL_RENDERER_PRELIT) != 0 && icon_renderer->follow_state;
|
|
|
|
/* check whether the icon is affected by the expose event */
|
|
if (gdk_rectangle_intersect (&clip_area, &icon_area, NULL))
|
|
{
|
|
/* use a translucent icon to represent cutted and hidden files to the user */
|
|
clipboard = thunar_clipboard_manager_get_for_display (gtk_widget_get_display (widget));
|
|
if (thunar_clipboard_manager_has_cutted_file (clipboard, icon_renderer->file) && thunar_file_is_writable (icon_renderer->file))
|
|
{
|
|
/* 50% translucent for cutted files */
|
|
alpha = 0.50;
|
|
}
|
|
else if (thunar_file_is_hidden (icon_renderer->file))
|
|
{
|
|
/* 75% translucent for hidden files */
|
|
alpha = 0.75;
|
|
}
|
|
else
|
|
{
|
|
alpha = 1.00;
|
|
}
|
|
g_object_unref (G_OBJECT (clipboard));
|
|
|
|
/* render the invalid parts of the icon */
|
|
thunar_gdk_cairo_set_source_pixbuf (cr, icon, icon_area.x, icon_area.y, scale_factor);
|
|
cairo_paint_with_alpha (cr, alpha);
|
|
|
|
/* check if we should render an insensitive icon */
|
|
if (G_UNLIKELY (gtk_widget_get_state_flags (widget) == GTK_STATE_FLAG_INSENSITIVE || !gtk_cell_renderer_get_sensitive (renderer)))
|
|
thunar_icon_renderer_color_insensitive (cr, widget);
|
|
|
|
/* paint the lighten mask */
|
|
if (color_lighten)
|
|
thunar_icon_renderer_color_lighten (cr, widget);
|
|
|
|
/* paint the selected mask */
|
|
if (color_selected)
|
|
thunar_icon_renderer_color_selected (cr, widget);
|
|
}
|
|
|
|
/* release the file's icon */
|
|
g_object_unref (G_OBJECT (icon));
|
|
|
|
/* check if we should render emblems as well */
|
|
if (G_LIKELY (icon_renderer->emblems))
|
|
{
|
|
/* display the primary emblem as well (if any) */
|
|
emblems = thunar_file_get_emblem_names (icon_renderer->file);
|
|
if (G_UNLIKELY (emblems != NULL))
|
|
{
|
|
/* render up to MAX_EMBLEMS_PER_FILE emblems */
|
|
for (lp = emblems, position = 0; lp != NULL && position < MAX_EMBLEMS_PER_FILE; lp = lp->next)
|
|
{
|
|
/* calculate the emblem size */
|
|
emblem_size = MIN ((2 * icon_renderer->size) / 4, 32);
|
|
|
|
/* check if we have the emblem in the icon theme */
|
|
emblem = thunar_icon_factory_load_icon (icon_factory, lp->data, emblem_size, scale_factor, FALSE,
|
|
icon_renderer->use_symbolic_icons, context);
|
|
if (G_UNLIKELY (emblem == NULL))
|
|
continue;
|
|
|
|
/* determine the dimensions of the emblem */
|
|
emblem_area.width = gdk_pixbuf_get_width (emblem) / scale_factor;
|
|
emblem_area.height = gdk_pixbuf_get_height (emblem) / scale_factor;
|
|
|
|
/* shrink insane emblems */
|
|
if (G_UNLIKELY (MAX (emblem_area.width, emblem_area.height) > emblem_size))
|
|
{
|
|
/* scale down the emblem */
|
|
temp = exo_gdk_pixbuf_scale_ratio (emblem, emblem_size * scale_factor);
|
|
g_object_unref (G_OBJECT (emblem));
|
|
emblem = temp;
|
|
|
|
/* determine the size again */
|
|
emblem_area.width = gdk_pixbuf_get_width (emblem) / scale_factor;
|
|
emblem_area.height = gdk_pixbuf_get_height (emblem) / scale_factor;
|
|
}
|
|
|
|
/* determine a good position for the emblem, depending on the position index */
|
|
switch (position)
|
|
{
|
|
case 0: /* right/bottom */
|
|
emblem_area.x = MIN (icon_area.x + icon_area.width - emblem_area.width / 2,
|
|
cell_area->x + cell_area->width - emblem_area.width);
|
|
emblem_area.y = MIN (icon_area.y + icon_area.height - emblem_area.height / 2,
|
|
cell_area->y + cell_area->height - emblem_area.height);
|
|
break;
|
|
|
|
case 1: /* left/bottom */
|
|
emblem_area.x = MAX (icon_area.x - emblem_area.width / 2,
|
|
cell_area->x);
|
|
emblem_area.y = MIN (icon_area.y + icon_area.height - emblem_area.height / 2,
|
|
cell_area->y + cell_area->height - emblem_area.height);
|
|
break;
|
|
|
|
case 2: /* left/top */
|
|
emblem_area.x = MAX (icon_area.x - emblem_area.width / 2,
|
|
cell_area->x);
|
|
emblem_area.y = MAX (icon_area.y - emblem_area.height / 2,
|
|
cell_area->y);
|
|
break;
|
|
|
|
case 3: /* right/top */
|
|
emblem_area.x = MIN (icon_area.x + icon_area.width - emblem_area.width / 2,
|
|
cell_area->x + cell_area->width - emblem_area.width);
|
|
emblem_area.y = MAX (icon_area.y - emblem_area.height / 2,
|
|
cell_area->y);
|
|
break;
|
|
|
|
default:
|
|
_thunar_assert_not_reached ();
|
|
}
|
|
|
|
/* render the emblem */
|
|
if (gdk_rectangle_intersect (&clip_area, &emblem_area, NULL))
|
|
{
|
|
/* render the invalid parts of the icon */
|
|
thunar_gdk_cairo_set_source_pixbuf (cr, emblem, emblem_area.x, emblem_area.y, scale_factor);
|
|
cairo_paint (cr);
|
|
|
|
/* paint the lighten mask */
|
|
if (color_lighten)
|
|
thunar_icon_renderer_color_lighten (cr, widget);
|
|
|
|
/* paint the selected mask */
|
|
if (color_selected)
|
|
thunar_icon_renderer_color_selected (cr, widget);
|
|
}
|
|
|
|
/* release the emblem */
|
|
g_object_unref (G_OBJECT (emblem));
|
|
|
|
/* advance the position index */
|
|
++position;
|
|
}
|
|
|
|
/* release the emblem name list */
|
|
g_list_free_full (emblems, g_free);
|
|
}
|
|
}
|
|
|
|
/* release our reference on the icon factory */
|
|
g_object_unref (G_OBJECT (icon_factory));
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* 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);
|
|
}
|