diff --git a/libnemo-private/meson.build b/libnemo-private/meson.build index 16c061882..d31c3a39d 100644 --- a/libnemo-private/meson.build +++ b/libnemo-private/meson.build @@ -30,6 +30,8 @@ nemo_private_sources = [ 'nemo-directory-async.c', 'nemo-directory.c', 'nemo-dnd.c', + 'nemo-emblem.c', + 'nemo-emblemed-icon.c', 'nemo-entry.c', 'nemo-file-changes-queue.c', 'nemo-file-conflict-dialog.c', diff --git a/libnemo-private/nemo-emblem.c b/libnemo-private/nemo-emblem.c new file mode 100644 index 000000000..cab47fe3c --- /dev/null +++ b/libnemo-private/nemo-emblem.c @@ -0,0 +1,136 @@ +/* nemo-emblem.c - Custom emblem with size and position control + * + * Copyright (C) 2026 Linux Mint + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + */ + +#include +#include "nemo-emblem.h" + +struct _NemoEmblem { + GObject parent_instance; + + GIcon *icon; + NemoEmblemSize size; + NemoEmblemPosition position; +}; + +static void nemo_emblem_icon_iface_init (GIconIface *iface); + +G_DEFINE_TYPE_WITH_CODE (NemoEmblem, nemo_emblem, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_ICON, nemo_emblem_icon_iface_init)) + +static void +nemo_emblem_finalize (GObject *object) +{ + NemoEmblem *emblem = NEMO_EMBLEM (object); + + g_clear_object (&emblem->icon); + + G_OBJECT_CLASS (nemo_emblem_parent_class)->finalize (object); +} + +static guint +nemo_emblem_hash (GIcon *icon) +{ + NemoEmblem *emblem = NEMO_EMBLEM (icon); + + return g_icon_hash (emblem->icon) ^ (emblem->size << 8) ^ (emblem->position << 16); +} + +static gboolean +nemo_emblem_equal (GIcon *icon1, GIcon *icon2) +{ + NemoEmblem *a = NEMO_EMBLEM (icon1); + NemoEmblem *b = NEMO_EMBLEM (icon2); + + return g_icon_equal (a->icon, b->icon) && + a->size == b->size && + a->position == b->position; +} + +static GVariant * +nemo_emblem_serialize (GIcon *icon) +{ + NemoEmblem *emblem = NEMO_EMBLEM (icon); + GVariant *inner; + + inner = g_icon_serialize (emblem->icon); + if (inner == NULL) { + return NULL; + } + + GVariant *result = g_variant_new ("(vii)", inner, (gint32) emblem->size, (gint32) emblem->position); + return result; +} + +static void +nemo_emblem_icon_iface_init (GIconIface *iface) +{ + iface->hash = nemo_emblem_hash; + iface->equal = nemo_emblem_equal; + iface->serialize = nemo_emblem_serialize; +} + +static void +nemo_emblem_class_init (NemoEmblemClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = nemo_emblem_finalize; +} + +static void +nemo_emblem_init (NemoEmblem *emblem) +{ +} + +NemoEmblem * +nemo_emblem_new (GIcon *icon, + NemoEmblemSize size, + NemoEmblemPosition position) +{ + NemoEmblem *emblem; + + g_return_val_if_fail (G_IS_ICON (icon), NULL); + + emblem = g_object_new (NEMO_TYPE_EMBLEM, NULL); + emblem->icon = g_object_ref (icon); + emblem->size = size; + emblem->position = position; + + return emblem; +} + +GIcon * +nemo_emblem_get_icon (NemoEmblem *emblem) +{ + g_return_val_if_fail (NEMO_IS_EMBLEM (emblem), NULL); + + return emblem->icon; +} + +NemoEmblemSize +nemo_emblem_get_size (NemoEmblem *emblem) +{ + g_return_val_if_fail (NEMO_IS_EMBLEM (emblem), NEMO_EMBLEM_SIZE_SMALL); + + return emblem->size; +} + +NemoEmblemPosition +nemo_emblem_get_position (NemoEmblem *emblem) +{ + g_return_val_if_fail (NEMO_IS_EMBLEM (emblem), NEMO_EMBLEM_POSITION_DEFAULT); + + return emblem->position; +} diff --git a/libnemo-private/nemo-emblem.h b/libnemo-private/nemo-emblem.h new file mode 100644 index 000000000..22d5bd235 --- /dev/null +++ b/libnemo-private/nemo-emblem.h @@ -0,0 +1,51 @@ +/* nemo-emblem.h - Custom emblem with size and position control + * + * Copyright (C) 2026 Linux Mint + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + */ + +#ifndef NEMO_EMBLEM_H +#define NEMO_EMBLEM_H + +#include + +G_BEGIN_DECLS + +typedef enum { + NEMO_EMBLEM_SIZE_EXTRA_SMALL, /* ~15% of icon size */ + NEMO_EMBLEM_SIZE_SMALL, /* ~25% of icon size */ + NEMO_EMBLEM_SIZE_MEDIUM, /* ~33% of icon size */ + NEMO_EMBLEM_SIZE_LARGE /* ~50% of icon size */ +} NemoEmblemSize; + +typedef enum { + NEMO_EMBLEM_POSITION_DEFAULT, /* auto-assign: cycles LR -> LL -> UR -> UL */ + NEMO_EMBLEM_POSITION_UPPER_LEFT, + NEMO_EMBLEM_POSITION_UPPER_RIGHT, + NEMO_EMBLEM_POSITION_LOWER_LEFT, + NEMO_EMBLEM_POSITION_LOWER_RIGHT +} NemoEmblemPosition; + +#define NEMO_TYPE_EMBLEM (nemo_emblem_get_type ()) + +G_DECLARE_FINAL_TYPE (NemoEmblem, nemo_emblem, NEMO, EMBLEM, GObject) + +NemoEmblem * nemo_emblem_new (GIcon *icon, + NemoEmblemSize size, + NemoEmblemPosition position); +GIcon * nemo_emblem_get_icon (NemoEmblem *emblem); +NemoEmblemSize nemo_emblem_get_size (NemoEmblem *emblem); +NemoEmblemPosition nemo_emblem_get_position (NemoEmblem *emblem); + +G_END_DECLS + +#endif /* NEMO_EMBLEM_H */ diff --git a/libnemo-private/nemo-emblemed-icon.c b/libnemo-private/nemo-emblemed-icon.c new file mode 100644 index 000000000..c95f6bb17 --- /dev/null +++ b/libnemo-private/nemo-emblemed-icon.c @@ -0,0 +1,171 @@ +/* nemo-emblemed-icon.c - Icon with custom emblem compositing + * + * Copyright (C) 2026 Linux Mint + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + */ + +#include +#include "nemo-emblemed-icon.h" + +struct _NemoEmblemedIcon { + GObject parent_instance; + + GIcon *icon; + GList *emblems; +}; + +static void nemo_emblemed_icon_icon_iface_init (GIconIface *iface); + +G_DEFINE_TYPE_WITH_CODE (NemoEmblemedIcon, nemo_emblemed_icon, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_ICON, nemo_emblemed_icon_icon_iface_init)) + +static void +nemo_emblemed_icon_finalize (GObject *object) +{ + NemoEmblemedIcon *self = NEMO_EMBLEMED_ICON (object); + + g_clear_object (&self->icon); + g_list_free_full (self->emblems, g_object_unref); + + G_OBJECT_CLASS (nemo_emblemed_icon_parent_class)->finalize (object); +} + +static guint +nemo_emblemed_icon_hash (GIcon *icon) +{ + NemoEmblemedIcon *self = NEMO_EMBLEMED_ICON (icon); + guint hash; + GList *l; + + hash = g_icon_hash (self->icon); + + for (l = self->emblems; l != NULL; l = l->next) { + hash ^= g_icon_hash (G_ICON (l->data)); + } + + return hash; +} + +static gboolean +nemo_emblemed_icon_equal (GIcon *icon1, GIcon *icon2) +{ + NemoEmblemedIcon *a = NEMO_EMBLEMED_ICON (icon1); + NemoEmblemedIcon *b = NEMO_EMBLEMED_ICON (icon2); + GList *la, *lb; + + if (!g_icon_equal (a->icon, b->icon)) { + return FALSE; + } + + if (g_list_length (a->emblems) != g_list_length (b->emblems)) { + return FALSE; + } + + for (la = a->emblems, lb = b->emblems; la != NULL; la = la->next, lb = lb->next) { + if (!g_icon_equal (G_ICON (la->data), G_ICON (lb->data))) { + return FALSE; + } + } + + return TRUE; +} + +static GVariant * +nemo_emblemed_icon_serialize (GIcon *icon) +{ + NemoEmblemedIcon *self = NEMO_EMBLEMED_ICON (icon); + GVariantBuilder builder; + GVariant *inner; + GList *l; + + inner = g_icon_serialize (self->icon); + if (inner == NULL) { + return NULL; + } + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("av")); + + for (l = self->emblems; l != NULL; l = l->next) { + GVariant *emblem_v = g_icon_serialize (G_ICON (l->data)); + if (emblem_v != NULL) { + g_variant_builder_add (&builder, "v", emblem_v); + } + } + + return g_variant_new ("(vav)", inner, &builder); +} + +static void +nemo_emblemed_icon_icon_iface_init (GIconIface *iface) +{ + iface->hash = nemo_emblemed_icon_hash; + iface->equal = nemo_emblemed_icon_equal; + iface->serialize = nemo_emblemed_icon_serialize; +} + +static void +nemo_emblemed_icon_class_init (NemoEmblemedIconClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = nemo_emblemed_icon_finalize; +} + +static void +nemo_emblemed_icon_init (NemoEmblemedIcon *self) +{ +} + +GIcon * +nemo_emblemed_icon_new (GIcon *icon, + NemoEmblem *emblem) +{ + NemoEmblemedIcon *self; + + g_return_val_if_fail (G_IS_ICON (icon), NULL); + + self = g_object_new (NEMO_TYPE_EMBLEMED_ICON, NULL); + self->icon = g_object_ref (icon); + + if (emblem != NULL) { + self->emblems = g_list_append (self->emblems, g_object_ref (emblem)); + } + + return G_ICON (self); +} + +void +nemo_emblemed_icon_add_emblem (NemoEmblemedIcon *emblemed_icon, + NemoEmblem *emblem) +{ + g_return_if_fail (NEMO_IS_EMBLEMED_ICON (emblemed_icon)); + g_return_if_fail (NEMO_IS_EMBLEM (emblem)); + + emblemed_icon->emblems = g_list_append (emblemed_icon->emblems, + g_object_ref (emblem)); +} + +GIcon * +nemo_emblemed_icon_get_icon (NemoEmblemedIcon *emblemed_icon) +{ + g_return_val_if_fail (NEMO_IS_EMBLEMED_ICON (emblemed_icon), NULL); + + return emblemed_icon->icon; +} + +GList * +nemo_emblemed_icon_get_emblems (NemoEmblemedIcon *emblemed_icon) +{ + g_return_val_if_fail (NEMO_IS_EMBLEMED_ICON (emblemed_icon), NULL); + + return emblemed_icon->emblems; +} diff --git a/libnemo-private/nemo-emblemed-icon.h b/libnemo-private/nemo-emblemed-icon.h new file mode 100644 index 000000000..6db626efc --- /dev/null +++ b/libnemo-private/nemo-emblemed-icon.h @@ -0,0 +1,37 @@ +/* nemo-emblemed-icon.h - Icon with custom emblem compositing + * + * Copyright (C) 2026 Linux Mint + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + */ + +#ifndef NEMO_EMBLEMED_ICON_H +#define NEMO_EMBLEMED_ICON_H + +#include +#include "nemo-emblem.h" + +G_BEGIN_DECLS + +#define NEMO_TYPE_EMBLEMED_ICON (nemo_emblemed_icon_get_type ()) + +G_DECLARE_FINAL_TYPE (NemoEmblemedIcon, nemo_emblemed_icon, NEMO, EMBLEMED_ICON, GObject) + +GIcon * nemo_emblemed_icon_new (GIcon *icon, + NemoEmblem *emblem); +void nemo_emblemed_icon_add_emblem (NemoEmblemedIcon *emblemed_icon, + NemoEmblem *emblem); +GIcon * nemo_emblemed_icon_get_icon (NemoEmblemedIcon *emblemed_icon); +GList * nemo_emblemed_icon_get_emblems (NemoEmblemedIcon *emblemed_icon); + +G_END_DECLS + +#endif /* NEMO_EMBLEMED_ICON_H */ diff --git a/libnemo-private/nemo-icon-info.c b/libnemo-private/nemo-icon-info.c index 5be1c35ee..ee50d6c4d 100644 --- a/libnemo-private/nemo-icon-info.c +++ b/libnemo-private/nemo-icon-info.c @@ -23,6 +23,7 @@ #include "nemo-icon-info.h" #include "nemo-icon-names.h" #include "nemo-default-file-icon.h" +#include "nemo-emblemed-icon.h" #include #include @@ -283,6 +284,175 @@ icon_key_free (IconKey *key) g_free (key); } +static gdouble +nemo_emblem_size_get_ratio (NemoEmblemSize size) +{ + switch (size) { + case NEMO_EMBLEM_SIZE_EXTRA_SMALL: + return 0.20; + case NEMO_EMBLEM_SIZE_SMALL: + return 0.33; + case NEMO_EMBLEM_SIZE_MEDIUM: + return 0.45; + case NEMO_EMBLEM_SIZE_LARGE: + return 0.60; + default: + return 0.33; + } +} + +static NemoEmblemPosition +auto_position_order[] = { + NEMO_EMBLEM_POSITION_LOWER_RIGHT, + NEMO_EMBLEM_POSITION_LOWER_LEFT, + NEMO_EMBLEM_POSITION_UPPER_RIGHT, + NEMO_EMBLEM_POSITION_UPPER_LEFT, +}; + +static NemoIconInfo * +nemo_icon_info_lookup_emblemed (NemoEmblemedIcon *emblemed_icon, + int size, + int scale) +{ + GIcon *base_icon; + GList *emblems, *l; + NemoIconInfo *base_info; + GdkPixbuf *base_pixbuf, *result_pixbuf; + gint base_w, base_h, canvas_w, canvas_h, pad_x, pad_y; + gboolean corners_taken[5] = { FALSE }; + gint auto_idx = 0; + gint max_emblem_px = 0; + + base_icon = nemo_emblemed_icon_get_icon (emblemed_icon); + base_info = nemo_icon_info_lookup (base_icon, size, scale); + base_pixbuf = nemo_icon_info_get_pixbuf (base_info); + nemo_icon_info_unref (base_info); + + base_w = gdk_pixbuf_get_width (base_pixbuf); + base_h = gdk_pixbuf_get_height (base_pixbuf); + + emblems = nemo_emblemed_icon_get_emblems (emblemed_icon); + + for (l = emblems; l != NULL; l = l->next) { + NemoEmblem *emblem = NEMO_EMBLEM (l->data); + gdouble ratio = nemo_emblem_size_get_ratio (nemo_emblem_get_size (emblem)); + gint epx = MAX ((gint)(MAX (base_w, base_h) * ratio), 8); + if (epx > max_emblem_px) { + max_emblem_px = epx; + } + corners_taken[nemo_emblem_get_position (emblem)] = TRUE; + } + + pad_x = max_emblem_px > base_w ? (max_emblem_px - base_w + 1) / 2 : 0; + pad_y = max_emblem_px > base_h ? (max_emblem_px - base_h + 1) / 2 : 0; + + canvas_w = base_w + pad_x * 2; + canvas_h = base_h + pad_y * 2; + + result_pixbuf = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (base_pixbuf), + TRUE, + gdk_pixbuf_get_bits_per_sample (base_pixbuf), + canvas_w, canvas_h); + gdk_pixbuf_fill (result_pixbuf, 0x00000000); + + gdk_pixbuf_copy_area (base_pixbuf, 0, 0, base_w, base_h, + result_pixbuf, pad_x, pad_y); + g_object_unref (base_pixbuf); + + for (l = emblems; l != NULL; l = l->next) { + NemoEmblem *emblem = NEMO_EMBLEM (l->data); + GIcon *emblem_icon; + NemoEmblemPosition pos; + gdouble ratio; + gint emblem_px, dest_x, dest_y; + GtkIconTheme *icon_theme; + GtkIconInfo *emblem_gtkicon; + GdkPixbuf *emblem_pixbuf; + + emblem_icon = nemo_emblem_get_icon (emblem); + pos = nemo_emblem_get_position (emblem); + + if (pos == NEMO_EMBLEM_POSITION_DEFAULT) { + while (auto_idx < 4 && corners_taken[auto_position_order[auto_idx]]) { + auto_idx++; + } + + if (auto_idx < 4) { + pos = auto_position_order[auto_idx]; + corners_taken[pos] = TRUE; + auto_idx++; + } else { + pos = NEMO_EMBLEM_POSITION_LOWER_RIGHT; + } + } + + ratio = nemo_emblem_size_get_ratio (nemo_emblem_get_size (emblem)); + emblem_px = MAX ((gint)(MAX (base_w, base_h) * ratio), 8); + + icon_theme = gtk_icon_theme_get_default (); + emblem_gtkicon = gtk_icon_theme_lookup_by_gicon_for_scale (icon_theme, + emblem_icon, + emblem_px / scale, + scale, + GTK_ICON_LOOKUP_FORCE_SIZE); + if (emblem_gtkicon == NULL) { + continue; + } + + emblem_pixbuf = gtk_icon_info_load_icon (emblem_gtkicon, NULL); + g_object_unref (emblem_gtkicon); + + if (emblem_pixbuf == NULL) { + continue; + } + + gint ew = gdk_pixbuf_get_width (emblem_pixbuf); + gint eh = gdk_pixbuf_get_height (emblem_pixbuf); + + switch (pos) { + case NEMO_EMBLEM_POSITION_LOWER_RIGHT: + dest_x = canvas_w - ew; + dest_y = canvas_h - eh; + break; + case NEMO_EMBLEM_POSITION_LOWER_LEFT: + dest_x = 0; + dest_y = canvas_h - eh; + break; + case NEMO_EMBLEM_POSITION_UPPER_RIGHT: + dest_x = canvas_w - ew; + dest_y = 0; + break; + case NEMO_EMBLEM_POSITION_UPPER_LEFT: + dest_x = 0; + dest_y = 0; + break; + default: + dest_x = canvas_w - ew; + dest_y = canvas_h - eh; + break; + } + + dest_x = MAX (dest_x, 0); + dest_y = MAX (dest_y, 0); + + gdk_pixbuf_composite (emblem_pixbuf, result_pixbuf, + dest_x, dest_y, + MIN (ew, canvas_w - dest_x), + MIN (eh, canvas_h - dest_y), + dest_x, dest_y, + 1.0, 1.0, + GDK_INTERP_BILINEAR, + 255); + + g_object_unref (emblem_pixbuf); + } + + NemoIconInfo *icon_info = nemo_icon_info_new_for_pixbuf (result_pixbuf, scale); + g_object_unref (result_pixbuf); + + return icon_info; +} + NemoIconInfo * nemo_icon_info_lookup (GIcon *icon, int size, @@ -293,6 +463,10 @@ nemo_icon_info_lookup (GIcon *icon, NemoIconInfo *icon_info; + if (NEMO_IS_EMBLEMED_ICON (icon)) { + return nemo_icon_info_lookup_emblemed (NEMO_EMBLEMED_ICON (icon), size, scale); + } + icon_theme = gtk_icon_theme_get_default (); if (G_IS_LOADABLE_ICON (icon)) { diff --git a/src/nemo-icon-view-container.c b/src/nemo-icon-view-container.c index 78bb24409..63edc2e29 100644 --- a/src/nemo-icon-view-container.c +++ b/src/nemo-icon-view-container.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #define DEBUG_FLAG NEMO_DEBUG_ICON_CONTAINER @@ -92,9 +93,8 @@ nemo_icon_view_container_get_icon_images (NemoIconContainer *container, NemoFile *file; NemoFileIconFlags flags; NemoIconInfo *icon_info; - GdkPixbuf *pixbuf; GIcon *emblemed_icon; - GEmblem *emblem; + NemoEmblem *emblem; GList *emblem_icons, *l; gint scale; @@ -125,51 +125,20 @@ nemo_icon_view_container_get_icon_images (NemoIconContainer *container, /* apply emblems */ if (emblem_icons != NULL) { - gint w, h, s; - gboolean bad_ratio; + GdkPixbuf *pixbuf = nemo_icon_info_get_pixbuf (icon_info); + emblemed_icon = nemo_emblemed_icon_new (G_ICON (pixbuf), NULL); - l = emblem_icons; - - pixbuf = nemo_icon_info_get_pixbuf (icon_info); - - w = gdk_pixbuf_get_width (pixbuf); - h = gdk_pixbuf_get_height (pixbuf); - - s = MAX (w, h); - if (s < size) - size = s; - - bad_ratio = (int)nemo_icon_get_emblem_size_for_icon_size (size) * scale > (int)(w * 0.75) || - (int)nemo_icon_get_emblem_size_for_icon_size (size) * scale > (int)(h * 0.75); - - if (bad_ratio) - goto skip_emblem; /* Would prefer to not use goto, but - * I don't want to do these checks on - * non-emblemed icons (the majority) - * as it would be too costly */ - - emblem = g_emblem_new (l->data); - - emblemed_icon = g_emblemed_icon_new (G_ICON (pixbuf), emblem); - g_object_unref (emblem); - - for (l = l->next; l != NULL; l = l->next) { - emblem = g_emblem_new (l->data); - g_emblemed_icon_add_emblem (G_EMBLEMED_ICON (emblemed_icon), - emblem); - g_object_unref (emblem); - } + for (l = emblem_icons; l != NULL; l = l->next) { + emblem = nemo_emblem_new (l->data, NEMO_EMBLEM_SIZE_MEDIUM, NEMO_EMBLEM_POSITION_DEFAULT); + nemo_emblemed_icon_add_emblem (NEMO_EMBLEMED_ICON (emblemed_icon), emblem); + g_object_unref (emblem); + } nemo_icon_info_clear (&icon_info); - icon_info = nemo_icon_info_lookup (emblemed_icon, size, scale); + icon_info = nemo_icon_info_lookup (emblemed_icon, size, scale); g_object_unref (emblemed_icon); + g_object_unref (pixbuf); -skip_emblem: - g_object_unref (pixbuf); - - } - - if (emblem_icons != NULL) { g_list_free_full (emblem_icons, g_object_unref); } diff --git a/src/nemo-icon-view-grid-container.c b/src/nemo-icon-view-grid-container.c index cfdb72595..572176b3f 100644 --- a/src/nemo-icon-view-grid-container.c +++ b/src/nemo-icon-view-grid-container.c @@ -43,6 +43,7 @@ #include #include #include +#include static void update_layout_constants (NemoIconContainer *container); @@ -71,9 +72,8 @@ nemo_icon_view_grid_container_get_icon_images (NemoIconContainer *container, NemoFile *file; NemoFileIconFlags flags; NemoIconInfo *icon_info; - GdkPixbuf *pixbuf; GIcon *emblemed_icon; - GEmblem *emblem; + NemoEmblem *emblem; GList *emblem_icons, *l; gint scale; @@ -102,51 +102,20 @@ nemo_icon_view_grid_container_get_icon_images (NemoIconContainer *container, /* apply emblems */ if (emblem_icons != NULL) { - gint w, h, s; - gboolean bad_ratio; + GdkPixbuf *pixbuf = nemo_icon_info_get_pixbuf (icon_info); + emblemed_icon = nemo_emblemed_icon_new (G_ICON (pixbuf), NULL); - l = emblem_icons; - - pixbuf = nemo_icon_info_get_pixbuf (icon_info); - - w = gdk_pixbuf_get_width (pixbuf); - h = gdk_pixbuf_get_height (pixbuf); - - s = MAX (w, h); - if (s < size) - size = s; - - bad_ratio = (int)nemo_icon_get_emblem_size_for_icon_size (size) * scale > (int)(w * 0.75) || - (int)nemo_icon_get_emblem_size_for_icon_size (size) * scale > (int)(h * 0.75); - - if (bad_ratio) - goto skip_emblem; /* Would prefer to not use goto, but - * I don't want to do these checks on - * non-emblemed icons (the majority) - * as it would be too costly */ - - emblem = g_emblem_new (l->data); - - emblemed_icon = g_emblemed_icon_new (G_ICON (pixbuf), emblem); - g_object_unref (emblem); - - for (l = l->next; l != NULL; l = l->next) { - emblem = g_emblem_new (l->data); - g_emblemed_icon_add_emblem (G_EMBLEMED_ICON (emblemed_icon), - emblem); - g_object_unref (emblem); - } + for (l = emblem_icons; l != NULL; l = l->next) { + emblem = nemo_emblem_new (l->data, NEMO_EMBLEM_SIZE_MEDIUM, NEMO_EMBLEM_POSITION_DEFAULT); + nemo_emblemed_icon_add_emblem (NEMO_EMBLEMED_ICON (emblemed_icon), emblem); + g_object_unref (emblem); + } - nemo_icon_info_clear (&icon_info); - icon_info = nemo_icon_info_lookup (emblemed_icon, size, scale); + nemo_icon_info_clear (&icon_info); + icon_info = nemo_icon_info_lookup (emblemed_icon, size, scale); g_object_unref (emblemed_icon); + g_object_unref (pixbuf); -skip_emblem: - g_object_unref (pixbuf); - - } - - if (emblem_icons != NULL) { g_list_free_full (emblem_icons, g_object_unref); } diff --git a/src/nemo-list-model.c b/src/nemo-list-model.c index 6f8a454f8..aee3eb9d5 100644 --- a/src/nemo-list-model.c +++ b/src/nemo-list-model.c @@ -38,6 +38,7 @@ #include #include #include +#include enum { SUBDIRECTORY_UNLOADED, @@ -350,36 +351,21 @@ nemo_list_model_get_value (GtkTreeModel *tree_model, GtkTreeIter *iter, int colu if (emblem_icons) { GdkPixbuf *initial_pixbuf; - GIcon *gicon, *emblemed_icon, *emblem_icon; - GEmblem *emblem; - gint w, h, s; - gboolean bad_ratio; + GIcon *gicon; + NemoEmblem *emblem; initial_pixbuf = nemo_icon_info_get_pixbuf_at_size (icon_info, icon_size * icon_scale); - - w = gdk_pixbuf_get_width (initial_pixbuf); - h = gdk_pixbuf_get_height (initial_pixbuf); - - s = MAX (w, h); - if (s < icon_size) - icon_size = s; - - bad_ratio = (int)(nemo_icon_get_emblem_size_for_icon_size (icon_size) * icon_scale) > (int)(w * 0.75) || - (int)(nemo_icon_get_emblem_size_for_icon_size (icon_size) * icon_scale) > (int)(h * 0.75); - gicon = G_ICON (initial_pixbuf); - /* pick only the first emblem we can render for the list view */ - for (l = emblem_icons; !bad_ratio && l != NULL; l = l->next) { - emblem_icon = l->data; - emblem = g_emblem_new (emblem_icon); - emblemed_icon = g_emblemed_icon_new (gicon, emblem); + /* pick only the first emblem for the list view */ + l = emblem_icons; + if (l != NULL) { + emblem = nemo_emblem_new (l->data, NEMO_EMBLEM_SIZE_MEDIUM, NEMO_EMBLEM_POSITION_LOWER_RIGHT); + GIcon *emblemed_icon = nemo_emblemed_icon_new (gicon, emblem); g_object_unref (gicon); g_object_unref (emblem); gicon = emblemed_icon; - - break; } nemo_icon_info_clear (&icon_info); diff --git a/src/nemo-tree-sidebar-model.c b/src/nemo-tree-sidebar-model.c index 92fdfcec7..044a87eee 100644 --- a/src/nemo-tree-sidebar-model.c +++ b/src/nemo-tree-sidebar-model.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -264,36 +265,36 @@ get_menu_icon_for_file (TreeNode *node, NemoFileIconFlags flags) { NemoFile *parent_file; - GIcon *gicon, *emblem_icon, *emblemed_icon; - GEmblem *emblem; - int size; - GList *emblem_icons, *l; + GIcon *gicon; + int size; + GList *emblem_icons, *l; - size = nemo_get_icon_size_for_stock_size (GTK_ICON_SIZE_MENU); - gicon = G_ICON (nemo_file_get_icon_pixbuf (file, size, TRUE, node->icon_scale, flags)); + size = nemo_get_icon_size_for_stock_size (GTK_ICON_SIZE_MENU); + gicon = G_ICON (nemo_file_get_icon_pixbuf (file, size, TRUE, node->icon_scale, flags)); parent_file = NULL; - if (node->parent && node->parent->file) { + if (node->parent && node->parent->file) { parent_file = node->parent->file; - } + } - emblem_icons = nemo_file_get_emblem_icons (node->file, parent_file); + emblem_icons = nemo_file_get_emblem_icons (node->file, parent_file); - /* pick only the first emblem we can render for the tree view */ - for (l = emblem_icons; l != NULL; l = l->next) { - emblem_icon = l->data; - emblem = g_emblem_new (emblem_icon); - emblemed_icon = g_emblemed_icon_new (gicon, emblem); + /* pick only the first emblem for the tree view */ + l = emblem_icons; + if (l != NULL) { + NemoEmblem *emblem; + GIcon *emblemed_icon; - g_object_unref (gicon); - g_object_unref (emblem); - gicon = emblemed_icon; + emblem = nemo_emblem_new (l->data, NEMO_EMBLEM_SIZE_MEDIUM, NEMO_EMBLEM_POSITION_LOWER_RIGHT); + emblemed_icon = nemo_emblemed_icon_new (gicon, emblem); - break; - } + g_object_unref (gicon); + g_object_unref (emblem); + gicon = emblemed_icon; + } - g_list_free_full (emblem_icons, g_object_unref); + g_list_free_full (emblem_icons, g_object_unref); return gicon; }