* src/folder.[ch]
[claws.git] / src / imageview.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 1999-2002 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/gtkpixmap.h>
27
28 #if HAVE_GDK_PIXBUF
29 #  include <gdk-pixbuf/gdk-pixbuf.h>
30 #else
31 #if HAVE_GDK_IMLIB
32 #  include <gdk_imlib.h>
33 #endif
34 #endif /* HAVE_GDK_PIXBUF */
35
36 #include "intl.h"
37 #include "mainwindow.h"
38 #include "prefs_common.h"
39 #include "procmime.h"
40 #include "imageview.h"
41 #include "utils.h"
42
43 void get_resized_size (int w, int h, int aw, int ah, int *sw, int *sh);
44
45 ImageView *imageview_create(void)
46 {
47         ImageView *imageview;
48         GtkWidget *scrolledwin;
49
50         debug_print("Creating image view...\n");
51         imageview = g_new0(ImageView, 1);
52
53         scrolledwin = gtk_scrolled_window_new(NULL, NULL);
54         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
55                                        GTK_POLICY_AUTOMATIC,
56                                        GTK_POLICY_AUTOMATIC);
57         gtk_widget_set_usize(scrolledwin, prefs_common.mainview_width, -1);
58
59         gtk_widget_show_all(scrolledwin);
60
61         imageview->scrolledwin  = scrolledwin;
62         imageview->image        = NULL;
63
64         return imageview;
65 }
66
67 void imageview_init(ImageView *imageview)
68 {
69 }
70
71 #if HAVE_GDK_PIXBUF
72 void imageview_show_image(ImageView *imageview, MimeInfo *mimeinfo,
73                           const gchar *file)
74 {
75         GdkPixbuf *pixbuf;
76         GdkPixbuf *pixbuf_scaled;
77         GdkPixmap *pixmap;
78         GdkBitmap *mask;
79         int avail_height = imageview->scrolledwin->parent->allocation.height - 10;
80         int avail_width  = imageview->scrolledwin->parent->allocation.width - 10;
81         int sized_height = -1;
82         int sized_width  = -1;
83         
84         imageview_clear(imageview);
85
86         pixbuf = gdk_pixbuf_new_from_file(file);
87
88         if (!pixbuf) {
89                 g_warning(_("Can't load the image."));  
90                 return;
91         }
92
93         if (imageview->messageview->mainwin)
94                 main_window_cursor_wait(imageview->messageview->mainwin);
95         
96         get_resized_size (gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf), 
97                           avail_width, avail_height, &sized_width, &sized_height);
98         
99         pixbuf_scaled = gdk_pixbuf_scale_simple (pixbuf, sized_width, sized_height, 0);
100         
101         gdk_pixbuf_render_pixmap_and_mask(pixbuf_scaled, &pixmap, &mask, 0);
102
103         if (!imageview->image) {
104                 imageview->image = gtk_pixmap_new(pixmap, mask);
105
106                 gtk_scrolled_window_add_with_viewport
107                         (GTK_SCROLLED_WINDOW(imageview->scrolledwin),
108                          imageview->image);
109         } else
110                 gtk_pixmap_set(GTK_PIXMAP(imageview->image), pixmap, mask);
111
112         gtk_widget_show(imageview->image);
113
114         gdk_pixbuf_unref(pixbuf);
115
116         if (imageview->messageview->mainwin)
117                 main_window_cursor_normal(imageview->messageview->mainwin);
118 }
119 #else
120 #if HAVE_GDK_IMLIB
121 void imageview_show_image(ImageView *imageview, MimeInfo *mimeinfo,
122                           const gchar *file)
123 {
124         GdkImlibImage *im;
125         int avail_height = imageview->scrolledwin->parent->allocation.height - 10;
126         int avail_width  = imageview->scrolledwin->parent->allocation.width - 10;
127         int sized_height = -1;
128         int sized_width  = -1;
129
130         imageview_clear(imageview);
131
132         im = gdk_imlib_load_image((gchar *)file);
133
134         if (!im) {
135                 g_warning(_("Can't load the image."));  
136                 return;
137         }
138
139         if (imageview->messageview->mainwin)
140                 main_window_cursor_wait(imageview->messageview->mainwin);
141
142         get_resized_size (im->rgb_width, im->rgb_height, 
143                           avail_width, avail_height, &sized_width, &sized_height);
144
145         gdk_imlib_render(im, sized_width, sized_height);
146
147         if (!imageview->image) {
148                 imageview->image = gtk_pixmap_new(gdk_imlib_move_image(im),
149                                                   gdk_imlib_move_mask(im));
150
151                 gtk_scrolled_window_add_with_viewport
152                         (GTK_SCROLLED_WINDOW(imageview->scrolledwin),
153                          imageview->image);
154         } else
155                 gtk_pixmap_set(GTK_PIXMAP(imageview->image),
156                                gdk_imlib_move_image(im),
157                                gdk_imlib_move_mask(im));      
158
159         gtk_widget_show(imageview->image);
160
161         gdk_imlib_destroy_image(im);
162
163         if (imageview->messageview->mainwin)
164                 main_window_cursor_normal(imageview->messageview->mainwin);
165 }
166 #else
167 void imageview_show_image(ImageView *imageview, MimeInfo *mimeinfo,
168                           const gchar *file)
169 {
170 }
171 #endif /* HAVE_GDK_IMLIB */
172 #endif /* HAVE_GDK_PIXBUF */
173
174 void imageview_clear(ImageView *imageview)
175 {
176         GtkAdjustment *hadj, *vadj;
177
178         if (imageview->image)
179                 gtk_pixmap_set(GTK_PIXMAP(imageview->image), NULL, NULL);
180         hadj = gtk_scrolled_window_get_hadjustment
181                 (GTK_SCROLLED_WINDOW(imageview->scrolledwin));
182         gtk_adjustment_set_value(hadj, 0.0);
183         vadj = gtk_scrolled_window_get_vadjustment
184                 (GTK_SCROLLED_WINDOW(imageview->scrolledwin));
185         gtk_adjustment_set_value(vadj, 0.0);
186 }
187
188 void imageview_destroy(ImageView *imageview)
189 {
190         g_free(imageview);
191 }
192
193 void get_resized_size (int w, int h, int aw, int ah, int *sw, int *sh) {
194         
195         float wratio = 1.0;
196         float hratio = 1.0;
197         float ratio  = 1.0;
198
199         if (w > aw)
200                 wratio = (float)((float)aw/(float)w);
201         if (h > ah)
202                 hratio = (float)((float)ah/(float)h);
203         
204         ratio = (wratio > hratio) ? hratio : wratio;
205
206         *sw = (int)(w * ratio);
207         *sh = (int)(h * ratio);
208         
209         /* be paranoid */
210         if (*sw <= 0 || *sh <= 0) {
211                 *sw = w;
212                 *sh = h;
213         }
214 }