Statistics
| Revision:

root / src / imageview.c @ 1

History | View | Annotate | Download (6.02 KB)

1
/*
2
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3
 * Copyright (C) 1999-2004 Hiroyuki Yamamoto
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
 */
19

    
20
#ifdef HAVE_CONFIG_H
21
#  include "config.h"
22
#endif
23

    
24
#include <glib.h>
25
#include <gtk/gtkscrolledwindow.h>
26
#include <gtk/gtkimage.h>
27

    
28
#if HAVE_GDK_PIXBUF
29
#  include <gdk-pixbuf/gdk-pixbuf.h>
30
#endif /* HAVE_GDK_PIXBUF */
31

    
32
#include "intl.h"
33
#include "mainwindow.h"
34
#include "prefs_common.h"
35
#include "procmime.h"
36
#include "imageview.h"
37
#include "utils.h"
38

    
39
static void get_resized_size        (gint         w,
40
                                 gint         h,
41
                                 gint         aw,
42
                                 gint         ah,
43
                                 gint        *sw,
44
                                 gint        *sh);
45

    
46
static gint button_press_cb        (GtkWidget        *widget,
47
                                 GdkEventButton        *event,
48
                                 gpointer         data);
49
static void size_allocate_cb        (GtkWidget        *widget,
50
                                 GtkAllocation        *allocation,
51
                                 gpointer         data);
52

    
53
ImageView *imageview_create(void)
54
{
55
        ImageView *imageview;
56
        GtkWidget *scrolledwin;
57

    
58
        debug_print(_("Creating image view...\n"));
59
        imageview = g_new0(ImageView, 1);
60

    
61
        scrolledwin = gtk_scrolled_window_new(NULL, NULL);
62
        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
63
                                       GTK_POLICY_AUTOMATIC,
64
                                       GTK_POLICY_AUTOMATIC);
65
        gtk_widget_set_size_request
66
                (scrolledwin, prefs_common.mainview_width, -1);
67

    
68
        g_signal_connect(G_OBJECT(scrolledwin), "button_press_event",
69
                         G_CALLBACK(button_press_cb), imageview);
70
        g_signal_connect(G_OBJECT(scrolledwin), "size_allocate",
71
                         G_CALLBACK(size_allocate_cb), imageview);
72

    
73
        gtk_widget_show_all(scrolledwin);
74

    
75
        imageview->scrolledwin  = scrolledwin;
76
        imageview->image        = NULL;
77
        imageview->image_data   = NULL;
78
        imageview->resize       = FALSE;
79
        imageview->resizing     = FALSE;
80

    
81
        return imageview;
82
}
83

    
84
void imageview_init(ImageView *imageview)
85
{
86
}
87

    
88
#if HAVE_GDK_PIXBUF
89
void imageview_show_image(ImageView *imageview, MimeInfo *mimeinfo,
90
                          const gchar *file, gboolean resize)
91
{
92
        GdkPixbuf *pixbuf;
93
        gint avail_width;
94
        gint avail_height;
95
        gint new_width;
96
        gint new_height;
97
        GError *error = NULL;
98

    
99
        g_return_if_fail(imageview != NULL);
100

    
101
        if (file) {
102
                imageview_clear(imageview);
103
                pixbuf = gdk_pixbuf_new_from_file(file, &error);
104
                imageview->image_data = pixbuf;
105
        } else {
106
                pixbuf = (GdkPixbuf *)imageview->image_data;
107
        }
108

    
109
        if (error != NULL) {
110
                g_warning("%s\n", error->message);
111
                g_error_free(error);
112
        }
113

    
114
        if (!pixbuf) {
115
                g_warning(_("Can't load the image."));        
116
                return;
117
        }
118

    
119
        imageview->resize = resize;
120

    
121
        if (resize) {
122
                GdkPixbuf *pixbuf_scaled;
123

    
124
                avail_width = imageview->scrolledwin->parent->allocation.width;
125
                avail_height = imageview->scrolledwin->parent->allocation.height;
126
                if (avail_width > 8) avail_width -= 8;
127
                if (avail_height > 8) avail_height -= 8;
128

    
129
                get_resized_size(gdk_pixbuf_get_width(pixbuf),
130
                                 gdk_pixbuf_get_height(pixbuf),
131
                                 avail_width, avail_height,
132
                                 &new_width, &new_height);
133

    
134
                pixbuf_scaled = gdk_pixbuf_scale_simple
135
                        (pixbuf, new_width, new_height, GDK_INTERP_BILINEAR);
136
                pixbuf = pixbuf_scaled;
137
        } else
138
                g_object_ref(pixbuf);
139

    
140
        if (!imageview->image) {
141
                imageview->image = gtk_image_new_from_pixbuf(pixbuf);
142

    
143
                gtk_scrolled_window_add_with_viewport
144
                        (GTK_SCROLLED_WINDOW(imageview->scrolledwin),
145
                         imageview->image);
146
        } else
147
                gtk_image_set_from_pixbuf(GTK_IMAGE(imageview->image), pixbuf);
148

    
149
        gdk_pixbuf_unref(pixbuf);
150

    
151
        gtk_widget_show(imageview->image);
152
}
153
#else
154
void imageview_show_image(ImageView *imageview, MimeInfo *mimeinfo,
155
                          const gchar *file, gboolean resize)
156
{
157
}
158
#endif /* HAVE_GDK_PIXBUF */
159

    
160
void imageview_clear(ImageView *imageview)
161
{
162
        GtkAdjustment *hadj, *vadj;
163

    
164
        if (imageview->image)
165
                gtk_image_set_from_pixmap(GTK_IMAGE(imageview->image),
166
                                          NULL, NULL);
167
        hadj = gtk_scrolled_window_get_hadjustment
168
                (GTK_SCROLLED_WINDOW(imageview->scrolledwin));
169
        gtk_adjustment_set_value(hadj, 0.0);
170
        vadj = gtk_scrolled_window_get_vadjustment
171
                (GTK_SCROLLED_WINDOW(imageview->scrolledwin));
172
        gtk_adjustment_set_value(vadj, 0.0);
173

    
174
        if (imageview->image_data) {
175
#if HAVE_GDK_PIXBUF
176
                gdk_pixbuf_unref((GdkPixbuf *)imageview->image_data);
177
#endif
178
                imageview->image_data = NULL;
179
        }
180
}
181

    
182
void imageview_destroy(ImageView *imageview)
183
{
184
        imageview_clear(imageview);
185
        g_free(imageview);
186
}
187

    
188
static void get_resized_size(gint w, gint h, gint aw, gint ah,
189
                             gint *sw, gint *sh)
190
{
191
        gfloat wratio = 1.0;
192
        gfloat hratio = 1.0;
193
        gfloat ratio  = 1.0;
194

    
195
        if (w <= aw && h <= ah) {
196
                *sw = w;
197
                *sh = h;
198
                return;
199
        }
200

    
201
        if (w > aw)
202
                wratio = (gfloat)aw / (gfloat)w;
203
        if (h > ah)
204
                hratio = (gfloat)ah / (gfloat)h;
205

    
206
        ratio = (wratio > hratio) ? hratio : wratio;
207

    
208
        *sw = (gint)(w * ratio);
209
        *sh = (gint)(h * ratio);
210

    
211
        /* restrict minimum size */
212
        if (*sw < 16 || *sh < 16) {
213
                wratio = 16.0 / (gfloat)w;
214
                hratio = 16.0 / (gfloat)h;
215
                ratio = (wratio > hratio) ? wratio : hratio;
216
                if (ratio >= 1.0) {
217
                        *sw = w;
218
                        *sh = h;
219
                } else {
220
                        *sw = (gint)(w * ratio);
221
                        *sh = (gint)(h * ratio);
222
                }
223
        }
224
}
225

    
226
static gint button_press_cb(GtkWidget *widget, GdkEventButton *event,
227
                            gpointer data)
228
{
229
        ImageView *imageview = (ImageView *)data;
230

    
231
        if (event->button == 1 && imageview->image) {
232
                imageview_show_image(imageview, NULL, NULL, !imageview->resize);
233
                return TRUE;
234
        }
235
        return FALSE;
236
}
237

    
238
static void size_allocate_cb(GtkWidget *widget,GtkAllocation *allocation,
239
                             gpointer data)
240
{
241
        ImageView *imageview = (ImageView *)data;
242

    
243
        if (imageview->resize) {
244
                if (imageview->resizing) {
245
                        imageview->resizing = FALSE;
246
                        return;
247
                }
248
                imageview_show_image(imageview, NULL, NULL, TRUE);
249
                imageview->resizing = TRUE;
250
        }
251
}