Skip to content

Commit ff85d04

Browse files
committed
Fix resizing image.
1 parent f8cc3ab commit ff85d04

File tree

1 file changed

+94
-23
lines changed

1 file changed

+94
-23
lines changed

libnemo-private/nemo-preview-image.c

Lines changed: 94 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ struct _NemoPreviewImage {
3434
};
3535

3636
typedef struct {
37-
GtkWidget *image;
37+
GtkWidget *drawing_area;
3838
GtkWidget *message_label;
3939
NemoFile *file;
4040

@@ -45,12 +45,16 @@ typedef struct {
4545

4646
/* Keep reference to current pixbuf for quick scaling */
4747
GdkPixbuf *current_pixbuf;
48+
49+
/* Current surface to draw */
50+
cairo_surface_t *current_surface;
4851
} NemoPreviewImagePrivate;
4952

5053
G_DEFINE_TYPE_WITH_PRIVATE (NemoPreviewImage, nemo_preview_image, GTK_TYPE_BOX)
5154

5255
/* Forward declarations */
5356
static void on_size_allocate (GtkWidget *widget, GtkAllocation *allocation, gpointer user_data);
57+
static gboolean on_drawing_area_draw (GtkWidget *widget, cairo_t *cr, gpointer user_data);
5458

5559
static void
5660
nemo_preview_image_finalize (GObject *object)
@@ -71,6 +75,11 @@ nemo_preview_image_finalize (GObject *object)
7175
priv->current_pixbuf = NULL;
7276
}
7377

78+
if (priv->current_surface != NULL) {
79+
cairo_surface_destroy (priv->current_surface);
80+
priv->current_surface = NULL;
81+
}
82+
7483
if (priv->file != NULL) {
7584
nemo_file_unref (priv->file);
7685
priv->file = NULL;
@@ -91,12 +100,17 @@ nemo_preview_image_init (NemoPreviewImage *preview)
91100
priv->current_width = 0;
92101
priv->current_height = 0;
93102
priv->current_pixbuf = NULL;
94-
95-
/* Create image widget */
96-
priv->image = gtk_image_new ();
97-
gtk_widget_set_halign (priv->image, GTK_ALIGN_CENTER);
98-
gtk_widget_set_valign (priv->image, GTK_ALIGN_CENTER);
99-
gtk_box_pack_start (GTK_BOX (preview), priv->image, TRUE, TRUE, 0);
103+
priv->current_surface = NULL;
104+
105+
/* Create drawing area widget */
106+
priv->drawing_area = gtk_drawing_area_new ();
107+
gtk_widget_set_halign (priv->drawing_area, GTK_ALIGN_FILL);
108+
gtk_widget_set_valign (priv->drawing_area, GTK_ALIGN_FILL);
109+
gtk_widget_set_hexpand (priv->drawing_area, TRUE);
110+
gtk_widget_set_vexpand (priv->drawing_area, TRUE);
111+
g_signal_connect (priv->drawing_area, "draw",
112+
G_CALLBACK (on_drawing_area_draw), preview);
113+
gtk_box_pack_start (GTK_BOX (preview), priv->drawing_area, TRUE, TRUE, 0);
100114

101115
/* Create message label (hidden by default) */
102116
priv->message_label = gtk_label_new ("");
@@ -129,6 +143,42 @@ nemo_preview_image_new (void)
129143
NULL);
130144
}
131145

146+
static gboolean
147+
on_drawing_area_draw (GtkWidget *widget,
148+
cairo_t *cr,
149+
gpointer user_data)
150+
{
151+
NemoPreviewImage *preview = NEMO_PREVIEW_IMAGE (user_data);
152+
NemoPreviewImagePrivate *priv;
153+
gint widget_width, widget_height;
154+
gint surface_width, surface_height;
155+
gdouble x_offset, y_offset;
156+
gint scale_factor;
157+
158+
priv = nemo_preview_image_get_instance_private (preview);
159+
160+
if (priv->current_surface == NULL) {
161+
return FALSE;
162+
}
163+
164+
widget_width = gtk_widget_get_allocated_width (widget);
165+
widget_height = gtk_widget_get_allocated_height (widget);
166+
167+
/* Get surface dimensions - works for image surfaces created from pixbufs */
168+
scale_factor = gtk_widget_get_scale_factor (widget);
169+
surface_width = cairo_image_surface_get_width (priv->current_surface) / scale_factor;
170+
surface_height = cairo_image_surface_get_height (priv->current_surface) / scale_factor;
171+
172+
/* Center the image in the drawing area */
173+
x_offset = (widget_width - surface_width) / 2.0;
174+
y_offset = (widget_height - surface_height) / 2.0;
175+
176+
cairo_set_source_surface (cr, priv->current_surface, x_offset, y_offset);
177+
cairo_paint (cr);
178+
179+
return TRUE;
180+
}
181+
132182
static gboolean
133183
is_image_file (NemoFile *file)
134184
{
@@ -196,9 +246,13 @@ load_image_at_size (NemoPreviewImage *widget,
196246
surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, ui_scale, NULL);
197247

198248
if (surface != NULL) {
199-
gtk_image_set_from_surface (GTK_IMAGE (priv->image), surface);
200-
gtk_widget_show (priv->image);
201-
cairo_surface_destroy (surface);
249+
/* Replace old surface with new one */
250+
if (priv->current_surface != NULL) {
251+
cairo_surface_destroy (priv->current_surface);
252+
}
253+
priv->current_surface = surface;
254+
gtk_widget_show (priv->drawing_area);
255+
gtk_widget_queue_draw (priv->drawing_area);
202256
}
203257

204258
g_object_unref (pixbuf);
@@ -212,7 +266,7 @@ load_image_at_size (NemoPreviewImage *widget,
212266
gtk_label_set_text (GTK_LABEL (priv->message_label),
213267
_("(Failed to load image)"));
214268
gtk_widget_show (priv->message_label);
215-
gtk_widget_hide (priv->image);
269+
gtk_widget_hide (priv->drawing_area);
216270
}
217271

218272
g_free (path);
@@ -265,8 +319,12 @@ scale_current_pixbuf_to_size (NemoPreviewImage *widget,
265319
surface = gdk_cairo_surface_create_from_pixbuf (scaled_pixbuf, ui_scale, NULL);
266320

267321
if (surface != NULL) {
268-
gtk_image_set_from_surface (GTK_IMAGE (priv->image), surface);
269-
cairo_surface_destroy (surface);
322+
/* Replace old surface with new one */
323+
if (priv->current_surface != NULL) {
324+
cairo_surface_destroy (priv->current_surface);
325+
}
326+
priv->current_surface = surface;
327+
gtk_widget_queue_draw (priv->drawing_area);
270328
}
271329

272330
g_object_unref (scaled_pixbuf);
@@ -357,9 +415,12 @@ nemo_preview_image_set_file (NemoPreviewImage *widget,
357415
priv->file = file;
358416

359417
/* Clear current image */
360-
gtk_image_clear (GTK_IMAGE (priv->image));
418+
if (priv->current_surface != NULL) {
419+
cairo_surface_destroy (priv->current_surface);
420+
priv->current_surface = NULL;
421+
}
361422
gtk_widget_hide (priv->message_label);
362-
gtk_widget_hide (priv->image);
423+
gtk_widget_hide (priv->drawing_area);
363424
priv->current_width = 0;
364425
priv->current_height = 0;
365426

@@ -385,14 +446,17 @@ nemo_preview_image_set_file (NemoPreviewImage *widget,
385446
if (icon_pixbuf != NULL) {
386447
surface = gdk_cairo_surface_create_from_pixbuf (icon_pixbuf, ui_scale, NULL);
387448
if (surface != NULL) {
388-
gtk_image_set_from_surface (GTK_IMAGE (priv->image), surface);
389-
cairo_surface_destroy (surface);
449+
if (priv->current_surface != NULL) {
450+
cairo_surface_destroy (priv->current_surface);
451+
}
452+
priv->current_surface = surface;
390453
}
391454
g_object_unref (icon_pixbuf);
392455
}
393456

394457
gtk_label_set_text (GTK_LABEL (priv->message_label), _("(Folder)"));
395-
gtk_widget_show (priv->image);
458+
gtk_widget_show (priv->drawing_area);
459+
gtk_widget_queue_draw (priv->drawing_area);
396460
gtk_widget_show (priv->message_label);
397461
} else {
398462
/* Non-image file: show file icon */
@@ -404,15 +468,18 @@ nemo_preview_image_set_file (NemoPreviewImage *widget,
404468
if (icon_pixbuf != NULL) {
405469
surface = gdk_cairo_surface_create_from_pixbuf (icon_pixbuf, ui_scale, NULL);
406470
if (surface != NULL) {
407-
gtk_image_set_from_surface (GTK_IMAGE (priv->image), surface);
408-
cairo_surface_destroy (surface);
471+
if (priv->current_surface != NULL) {
472+
cairo_surface_destroy (priv->current_surface);
473+
}
474+
priv->current_surface = surface;
409475
}
410476
g_object_unref (icon_pixbuf);
411477
}
412478

413479
gtk_label_set_text (GTK_LABEL (priv->message_label),
414480
_("(Not an image file)"));
415-
gtk_widget_show (priv->image);
481+
gtk_widget_show (priv->drawing_area);
482+
gtk_widget_queue_draw (priv->drawing_area);
416483
gtk_widget_show (priv->message_label);
417484
}
418485
}
@@ -438,13 +505,17 @@ nemo_preview_image_clear (NemoPreviewImage *widget)
438505
priv->current_pixbuf = NULL;
439506
}
440507

508+
if (priv->current_surface != NULL) {
509+
cairo_surface_destroy (priv->current_surface);
510+
priv->current_surface = NULL;
511+
}
512+
441513
if (priv->file != NULL) {
442514
nemo_file_unref (priv->file);
443515
priv->file = NULL;
444516
}
445517

446-
gtk_image_clear (GTK_IMAGE (priv->image));
447-
gtk_widget_hide (priv->image);
518+
gtk_widget_hide (priv->drawing_area);
448519
gtk_widget_hide (priv->message_label);
449520
priv->current_width = 0;
450521
priv->current_height = 0;

0 commit comments

Comments
 (0)