rev |
line source |
meillo@17
|
1 #include <sys/types.h>
|
meillo@17
|
2 #include <sys/stat.h>
|
meillo@17
|
3 #include <unistd.h>
|
meillo@17
|
4 #include <string.h>
|
meillo@17
|
5 #include <stdio.h>
|
meillo@17
|
6
|
meillo@0
|
7 #include <gtk/gtk.h>
|
meillo@17
|
8 #include <gdk/gdkkeysyms.h>
|
meillo@17
|
9 #include <gdk-pixbuf/gdk-pixbuf.h>
|
meillo@0
|
10
|
meillo@17
|
11
|
meillo@17
|
12
|
meillo@17
|
13
|
meillo@17
|
14 GtkWidget* cropper_window;
|
meillo@17
|
15 char* image_filename;
|
meillo@17
|
16
|
meillo@17
|
17 /* from interface.h */
|
meillo@17
|
18 GtkWidget* create_cropper_window(void);
|
meillo@17
|
19 GtkWidget* image_area;
|
meillo@17
|
20 GdkPixbuf* image_buffer;
|
meillo@17
|
21
|
meillo@17
|
22 int w, h, x, y;
|
meillo@17
|
23
|
meillo@17
|
24 int image_width;
|
meillo@17
|
25 int image_height;
|
meillo@17
|
26 float inc = 0.3;
|
meillo@17
|
27 float zoom = 1.0;
|
meillo@17
|
28
|
meillo@17
|
29 /* from callbacks.h */
|
meillo@17
|
30 double ratio;
|
meillo@17
|
31
|
meillo@17
|
32
|
meillo@17
|
33
|
meillo@17
|
34
|
meillo@17
|
35 #define GLADE_HOOKUP_OBJECT(component,widget,name) \
|
meillo@17
|
36 g_object_set_data_full(G_OBJECT(component), name, \
|
meillo@17
|
37 gtk_widget_ref(widget),(GDestroyNotify) gtk_widget_unref)
|
meillo@17
|
38
|
meillo@17
|
39 #define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \
|
meillo@17
|
40 g_object_set_data(G_OBJECT(component), name, widget)
|
meillo@17
|
41
|
meillo@17
|
42
|
meillo@17
|
43 /*
|
meillo@17
|
44 * This function returns a widget in a component created by Glade.
|
meillo@17
|
45 * Call it with the toplevel widget in the component (i.e. a window/dialog),
|
meillo@17
|
46 * or alternatively any widget in the component, and the name of the widget
|
meillo@17
|
47 * you want returned.
|
meillo@17
|
48 */
|
meillo@17
|
49 GtkWidget*
|
meillo@17
|
50 lookup_widget(GtkWidget* widget, const gchar* widget_name)
|
meillo@17
|
51 {
|
meillo@17
|
52 GtkWidget* parent;
|
meillo@17
|
53 GtkWidget* found_widget;
|
meillo@17
|
54
|
meillo@17
|
55 for (;;) {
|
meillo@17
|
56 if (GTK_IS_MENU(widget)) {
|
meillo@17
|
57 parent = gtk_menu_get_attach_widget(GTK_MENU(widget));
|
meillo@17
|
58 } else {
|
meillo@17
|
59 parent = widget->parent;
|
meillo@17
|
60 }
|
meillo@17
|
61 if (!parent) {
|
meillo@17
|
62 parent = (GtkWidget*) g_object_get_data(G_OBJECT(widget), "GladeParentKey");
|
meillo@17
|
63 }
|
meillo@17
|
64 if (parent == NULL) {
|
meillo@17
|
65 break;
|
meillo@17
|
66 }
|
meillo@17
|
67 widget = parent;
|
meillo@17
|
68 }
|
meillo@17
|
69
|
meillo@17
|
70 found_widget = (GtkWidget*) g_object_get_data(G_OBJECT(widget), widget_name);
|
meillo@17
|
71 if (!found_widget) {
|
meillo@17
|
72 g_warning("Widget not found: %s", widget_name);
|
meillo@17
|
73 }
|
meillo@17
|
74 return found_widget;
|
meillo@17
|
75 }
|
meillo@17
|
76
|
meillo@17
|
77
|
meillo@17
|
78
|
meillo@17
|
79
|
meillo@17
|
80
|
meillo@17
|
81
|
meillo@17
|
82
|
meillo@17
|
83
|
meillo@17
|
84
|
meillo@17
|
85
|
meillo@17
|
86
|
meillo@17
|
87
|
meillo@17
|
88
|
meillo@17
|
89
|
meillo@17
|
90
|
meillo@17
|
91
|
meillo@17
|
92
|
meillo@17
|
93
|
meillo@17
|
94
|
meillo@17
|
95
|
meillo@17
|
96
|
meillo@17
|
97
|
meillo@17
|
98
|
meillo@17
|
99 /* zoom */
|
meillo@17
|
100 void
|
meillo@17
|
101 set_zoom()
|
meillo@17
|
102 {
|
meillo@17
|
103 static GdkPixbuf* pixbuf_new;
|
meillo@17
|
104 g_object_unref(pixbuf_new);
|
meillo@17
|
105
|
meillo@17
|
106 pixbuf_new = gdk_pixbuf_scale_simple(image_buffer, image_width*zoom, image_height*zoom,
|
meillo@17
|
107 GDK_INTERP_BILINEAR);
|
meillo@17
|
108 gtk_image_set_from_pixbuf((GtkImage*) lookup_widget(cropper_window, "image_area"), pixbuf_new);
|
meillo@17
|
109 }
|
meillo@17
|
110
|
meillo@17
|
111 void
|
meillo@17
|
112 on_zoom_in_button_clicked(GtkObject* object, gpointer user_data)
|
meillo@17
|
113 {
|
meillo@17
|
114 zoom *= 1 + inc;
|
meillo@17
|
115 set_zoom();
|
meillo@17
|
116 }
|
meillo@17
|
117
|
meillo@17
|
118 void
|
meillo@17
|
119 on_zoom_out_button_clicked(GtkObject* object, gpointer user_data)
|
meillo@17
|
120 {
|
meillo@17
|
121 zoom *= 1 - inc;
|
meillo@17
|
122 set_zoom();
|
meillo@17
|
123 }
|
meillo@17
|
124
|
meillo@17
|
125 void
|
meillo@17
|
126 on_zoom_100_button_clicked(GtkObject* object, gpointer user_data)
|
meillo@17
|
127 {
|
meillo@17
|
128 zoom = 1.0;
|
meillo@17
|
129 set_zoom();
|
meillo@17
|
130 }
|
meillo@17
|
131
|
meillo@17
|
132 void
|
meillo@17
|
133 on_zoom_fit_button_clicked(GtkObject* object, gpointer user_data)
|
meillo@17
|
134 {
|
meillo@17
|
135 int w, h;
|
meillo@17
|
136 float zw, zh;
|
meillo@17
|
137 GtkWidget* image_a;
|
meillo@17
|
138
|
meillo@17
|
139 image_a = (GtkWidget*) lookup_widget(cropper_window, "image_area");
|
meillo@17
|
140 gdk_drawable_get_size(image_a->window, &w, &h);
|
meillo@17
|
141
|
meillo@17
|
142 zw = w*1.0 / image_width;
|
meillo@17
|
143 zh = h*1.0 / image_height;
|
meillo@17
|
144
|
meillo@17
|
145 zoom = (zw < zh) ? zw : zh;
|
meillo@17
|
146 set_zoom();
|
meillo@17
|
147 }
|
meillo@17
|
148
|
meillo@17
|
149
|
meillo@17
|
150
|
meillo@17
|
151
|
meillo@17
|
152
|
meillo@17
|
153
|
meillo@17
|
154
|
meillo@17
|
155 void
|
meillo@17
|
156 crop(void)
|
meillo@17
|
157 {
|
meillo@17
|
158 char crop_call[256];
|
meillo@17
|
159
|
meillo@17
|
160 sprintf(crop_call, "echo \"convert -crop %ix%i+%i+%i %s cropped_%s\"",
|
meillo@19
|
161 w, h, x, y, image_filename, image_filename);
|
meillo@17
|
162 system(crop_call);
|
meillo@17
|
163 gtk_main_quit();
|
meillo@17
|
164 }
|
meillo@17
|
165
|
meillo@17
|
166
|
meillo@17
|
167 void
|
meillo@17
|
168 on_cropper_window_create(GtkObject* object, gpointer user_data)
|
meillo@17
|
169 {
|
meillo@17
|
170 image_width = gdk_pixbuf_get_width(image_buffer);
|
meillo@17
|
171 image_height = gdk_pixbuf_get_height(image_buffer);
|
meillo@17
|
172
|
meillo@17
|
173 /*
|
meillo@17
|
174 image_buffer = gdk_pixbuf_new_from_file(image_filename, NULL);
|
meillo@17
|
175 image_area = gtk_image_new_from_pixbuf(image_buffer);
|
meillo@17
|
176
|
meillo@17
|
177 int w, h;
|
meillo@17
|
178 GtkWidget* image_a;
|
meillo@17
|
179
|
meillo@17
|
180 image_a = (GtkWidget*) lookup_widget(cropper_window, "image_area");
|
meillo@17
|
181 gdk_drawable_get_size(image_a->window, &w, &h);
|
meillo@17
|
182
|
meillo@17
|
183 image_width = w - 200;
|
meillo@17
|
184 image_height = h - 150;
|
meillo@17
|
185 set_zoom();
|
meillo@17
|
186 */
|
meillo@17
|
187 }
|
meillo@17
|
188
|
meillo@17
|
189 void
|
meillo@17
|
190 on_cropper_window_destroy(GtkObject* object, gpointer user_data)
|
meillo@17
|
191 {
|
meillo@17
|
192 gtk_main_quit();
|
meillo@17
|
193 }
|
meillo@17
|
194
|
meillo@17
|
195
|
meillo@17
|
196
|
meillo@17
|
197
|
meillo@17
|
198 gboolean
|
meillo@17
|
199 on_key_press(GtkWidget* window, GdkEventKey* pKey, gpointer userdata)
|
meillo@17
|
200 {
|
meillo@17
|
201 if (pKey->type != GDK_KEY_PRESS) {
|
meillo@17
|
202 return FALSE;
|
meillo@17
|
203 }
|
meillo@17
|
204 switch (pKey->keyval) {
|
meillo@17
|
205 case GDK_q:
|
meillo@17
|
206 gtk_main_quit();
|
meillo@17
|
207 break;
|
meillo@17
|
208 case GDK_Return:
|
meillo@17
|
209 crop();
|
meillo@17
|
210 break;
|
meillo@17
|
211 case GDK_plus:
|
meillo@17
|
212 on_zoom_in_button_clicked(NULL, userdata);
|
meillo@17
|
213 break;
|
meillo@17
|
214 case GDK_minus:
|
meillo@17
|
215 on_zoom_out_button_clicked(NULL, userdata);
|
meillo@17
|
216 break;
|
meillo@17
|
217 case GDK_0:
|
meillo@17
|
218 on_zoom_100_button_clicked(NULL, userdata);
|
meillo@17
|
219 break;
|
meillo@17
|
220 case GDK_f:
|
meillo@17
|
221 on_zoom_fit_button_clicked(NULL, userdata);
|
meillo@17
|
222 break;
|
meillo@17
|
223 }
|
meillo@17
|
224 return TRUE;
|
meillo@17
|
225 }
|
meillo@17
|
226
|
meillo@17
|
227
|
meillo@17
|
228
|
meillo@17
|
229
|
meillo@17
|
230
|
meillo@19
|
231 GtkWidget*
|
meillo@19
|
232 create_cropper_window(void)
|
meillo@19
|
233 {
|
meillo@19
|
234 GtkWidget *cropper_window;
|
meillo@19
|
235 GtkWidget *dialog_vbox1;
|
meillo@19
|
236 GtkWidget *status;
|
meillo@19
|
237 GtkWidget *label1;
|
meillo@19
|
238 GtkWidget *label2;
|
meillo@19
|
239
|
meillo@19
|
240
|
meillo@19
|
241 cropper_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
meillo@19
|
242 gtk_widget_set_name(cropper_window, "cropper_window");
|
meillo@19
|
243 gtk_container_set_border_width(GTK_CONTAINER(cropper_window), 6);
|
meillo@19
|
244 gtk_window_set_title(GTK_WINDOW(cropper_window), "cropper-0.2");
|
meillo@19
|
245
|
meillo@19
|
246 dialog_vbox1 = gtk_vbox_new(FALSE, 6);
|
meillo@19
|
247 gtk_widget_set_name(dialog_vbox1, "dialog_vbox1");
|
meillo@19
|
248 gtk_widget_show(dialog_vbox1);
|
meillo@19
|
249 gtk_container_add(GTK_CONTAINER(cropper_window), dialog_vbox1);
|
meillo@19
|
250
|
meillo@19
|
251
|
meillo@19
|
252 status = gtk_hbox_new(FALSE, 0);
|
meillo@19
|
253 gtk_widget_set_name(status, "status");
|
meillo@19
|
254 gtk_widget_show(status);
|
meillo@19
|
255 gtk_box_pack_end(GTK_BOX(dialog_vbox1), status, FALSE, FALSE, 0);
|
meillo@19
|
256
|
meillo@19
|
257 label1 = gtk_label_new("zoom:");
|
meillo@19
|
258 gtk_widget_set_name(label1, "label1");
|
meillo@19
|
259 gtk_widget_show(label1);
|
meillo@19
|
260 gtk_box_pack_start(GTK_BOX(status), label1, FALSE, FALSE, 0);
|
meillo@19
|
261
|
meillo@19
|
262 label2 = gtk_label_new("1.0");
|
meillo@19
|
263 gtk_widget_set_name(label2, "label2");
|
meillo@19
|
264 gtk_widget_show(label2);
|
meillo@19
|
265 gtk_box_pack_start(GTK_BOX(status), label2, FALSE, FALSE, 0);
|
meillo@19
|
266
|
meillo@19
|
267 /* image_area */
|
meillo@19
|
268 image_buffer = gdk_pixbuf_new_from_file(image_filename, NULL);
|
meillo@19
|
269 image_area = gtk_image_new_from_pixbuf(image_buffer);
|
meillo@19
|
270
|
meillo@19
|
271 gtk_widget_set_name(image_area, "image_area");
|
meillo@19
|
272 gtk_widget_show(image_area);
|
meillo@19
|
273 gtk_box_pack_start(GTK_BOX(dialog_vbox1), image_area, TRUE, TRUE, 0);
|
meillo@19
|
274
|
meillo@19
|
275
|
meillo@19
|
276
|
meillo@19
|
277
|
meillo@19
|
278
|
meillo@19
|
279 g_signal_connect(G_OBJECT(cropper_window), "show",
|
meillo@19
|
280 G_CALLBACK(on_cropper_window_create), NULL);
|
meillo@19
|
281
|
meillo@19
|
282 g_signal_connect(G_OBJECT(cropper_window), "destroy",
|
meillo@19
|
283 G_CALLBACK(on_cropper_window_destroy), NULL);
|
meillo@19
|
284
|
meillo@19
|
285 g_signal_connect(cropper_window, "key-press-event",
|
meillo@19
|
286 G_CALLBACK(on_key_press), NULL);
|
meillo@19
|
287
|
meillo@19
|
288
|
meillo@19
|
289 /* Store pointers to all widgets, for use by lookup_widget(). */
|
meillo@19
|
290
|
meillo@19
|
291 GLADE_HOOKUP_OBJECT_NO_REF(cropper_window, cropper_window, "cropper_window");
|
meillo@19
|
292 GLADE_HOOKUP_OBJECT(cropper_window, dialog_vbox1, "dialog_vbox1");
|
meillo@19
|
293
|
meillo@19
|
294 GLADE_HOOKUP_OBJECT(cropper_window, label1, "label1");
|
meillo@19
|
295 GLADE_HOOKUP_OBJECT(cropper_window, label2, "label2");
|
meillo@19
|
296 GLADE_HOOKUP_OBJECT(cropper_window, status, "status");
|
meillo@19
|
297 GLADE_HOOKUP_OBJECT(cropper_window, image_area, "image_area");
|
meillo@19
|
298 GLADE_HOOKUP_OBJECT(cropper_window,(GtkWidget*) image_buffer, "image_buffer");
|
meillo@19
|
299
|
meillo@19
|
300
|
meillo@19
|
301 return cropper_window;
|
meillo@19
|
302 }
|
meillo@19
|
303
|
meillo@19
|
304
|
meillo@17
|
305
|
meillo@0
|
306
|
meillo@2
|
307
|
meillo@11
|
308 int
|
meillo@11
|
309 main(int argc, char* argv[])
|
meillo@11
|
310 {
|
meillo@4
|
311 /* commandline option handling */
|
meillo@11
|
312 if (argc != 2) {
|
meillo@10
|
313 g_print("cropper -- a crop frontend to convert\n");
|
meillo@10
|
314 g_print("usage: cropper IMAGE\n");
|
meillo@10
|
315 return 1;
|
meillo@4
|
316 }
|
meillo@4
|
317
|
meillo@11
|
318 image_filename = argv[1];
|
meillo@10
|
319 gtk_init(&argc, &argv);
|
meillo@4
|
320
|
meillo@10
|
321 cropper_window = create_cropper_window();
|
meillo@10
|
322 gtk_widget_show(cropper_window);
|
meillo@11
|
323 gtk_main();
|
meillo@0
|
324
|
meillo@10
|
325 return 0;
|
meillo@0
|
326 }
|