cropper
view cropper.c @ 18:9d6e8105b145
rename
author | meillo@marmaro.de |
---|---|
date | Thu, 04 Mar 2010 19:34:39 +0100 |
parents | main.c@4453456abad1 |
children | 762de8cee1e4 |
line source
1 #include <sys/types.h>
2 #include <sys/stat.h>
3 #include <unistd.h>
4 #include <string.h>
5 #include <stdio.h>
7 #include <gtk/gtk.h>
8 #include <gdk/gdkkeysyms.h>
9 #include <gdk-pixbuf/gdk-pixbuf.h>
14 GtkWidget* cropper_window;
15 char* image_filename;
17 /* from interface.h */
18 GtkWidget* create_cropper_window(void);
19 GtkWidget* image_area;
20 GdkPixbuf* image_buffer;
22 int w, h, x, y;
24 int image_width;
25 int image_height;
26 float inc = 0.3;
27 float zoom = 1.0;
29 /* from callbacks.h */
30 double ratio;
32 void crop(void);
33 gboolean on_key_press(GtkWidget* window, GdkEventKey* pKey, gpointer userdata);
34 void on_cropper_window_create(GtkObject* object, gpointer user_data);
35 void on_cropper_window_destroy(GtkObject* object, gpointer user_data);
41 #define GLADE_HOOKUP_OBJECT(component,widget,name) \
42 g_object_set_data_full(G_OBJECT(component), name, \
43 gtk_widget_ref(widget),(GDestroyNotify) gtk_widget_unref)
45 #define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \
46 g_object_set_data(G_OBJECT(component), name, widget)
49 /*
50 * This function returns a widget in a component created by Glade.
51 * Call it with the toplevel widget in the component (i.e. a window/dialog),
52 * or alternatively any widget in the component, and the name of the widget
53 * you want returned.
54 */
55 GtkWidget*
56 lookup_widget(GtkWidget* widget, const gchar* widget_name)
57 {
58 GtkWidget* parent;
59 GtkWidget* found_widget;
61 for (;;) {
62 if (GTK_IS_MENU(widget)) {
63 parent = gtk_menu_get_attach_widget(GTK_MENU(widget));
64 } else {
65 parent = widget->parent;
66 }
67 if (!parent) {
68 parent = (GtkWidget*) g_object_get_data(G_OBJECT(widget), "GladeParentKey");
69 }
70 if (parent == NULL) {
71 break;
72 }
73 widget = parent;
74 }
76 found_widget = (GtkWidget*) g_object_get_data(G_OBJECT(widget), widget_name);
77 if (!found_widget) {
78 g_warning("Widget not found: %s", widget_name);
79 }
80 return found_widget;
81 }
85 GtkWidget*
86 create_cropper_window(void)
87 {
88 GtkWidget *cropper_window;
89 GtkWidget *dialog_vbox1;
90 GtkWidget *status;
91 GtkWidget *label1;
92 GtkWidget *label2;
95 cropper_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
96 gtk_widget_set_name(cropper_window, "cropper_window");
97 gtk_container_set_border_width(GTK_CONTAINER(cropper_window), 6);
98 gtk_window_set_title(GTK_WINDOW(cropper_window), "cropper-0.2");
100 dialog_vbox1 = gtk_vbox_new(FALSE, 6);
101 gtk_widget_set_name(dialog_vbox1, "dialog_vbox1");
102 gtk_widget_show(dialog_vbox1);
103 gtk_container_add(GTK_CONTAINER(cropper_window), dialog_vbox1);
106 status = gtk_hbox_new(FALSE, 0);
107 gtk_widget_set_name(status, "status");
108 gtk_widget_show(status);
109 gtk_box_pack_end(GTK_BOX(dialog_vbox1), status, FALSE, FALSE, 0);
111 label1 = gtk_label_new("zoom:");
112 gtk_widget_set_name(label1, "label1");
113 gtk_widget_show(label1);
114 gtk_box_pack_start(GTK_BOX(status), label1, FALSE, FALSE, 0);
116 label2 = gtk_label_new("1.0");
117 gtk_widget_set_name(label2, "label2");
118 gtk_widget_show(label2);
119 gtk_box_pack_start(GTK_BOX(status), label2, FALSE, FALSE, 0);
121 /* image_area */
122 image_buffer = gdk_pixbuf_new_from_file(image_filename, NULL);
123 image_area = gtk_image_new_from_pixbuf(image_buffer);
125 gtk_widget_set_name(image_area, "image_area");
126 gtk_widget_show(image_area);
127 gtk_box_pack_start(GTK_BOX(dialog_vbox1), image_area, TRUE, TRUE, 0);
133 g_signal_connect(G_OBJECT(cropper_window), "show",
134 G_CALLBACK(on_cropper_window_create), NULL);
136 g_signal_connect(G_OBJECT(cropper_window), "destroy",
137 G_CALLBACK(on_cropper_window_destroy), NULL);
139 g_signal_connect(cropper_window, "key-press-event",
140 G_CALLBACK(on_key_press), NULL);
143 /* Store pointers to all widgets, for use by lookup_widget(). */
145 GLADE_HOOKUP_OBJECT_NO_REF(cropper_window, cropper_window, "cropper_window");
146 GLADE_HOOKUP_OBJECT(cropper_window, dialog_vbox1, "dialog_vbox1");
148 GLADE_HOOKUP_OBJECT(cropper_window, label1, "label1");
149 GLADE_HOOKUP_OBJECT(cropper_window, label2, "label2");
150 GLADE_HOOKUP_OBJECT(cropper_window, status, "status");
151 GLADE_HOOKUP_OBJECT(cropper_window, image_area, "image_area");
152 GLADE_HOOKUP_OBJECT(cropper_window,(GtkWidget*) image_buffer, "image_buffer");
155 return cropper_window;
156 }
178 void
179 update_title(char* zoom)
180 {
181 char title[128];
182 snprintf(title, 128, "cropper (%s) %dx%d+%d+%d", zoom, w, h, x, y);
183 gtk_window_set_title(GTK_WINDOW(cropper_window), title);
184 }
187 /* zoom */
188 void
189 set_zoom()
190 {
191 static GdkPixbuf* pixbuf_new;
192 g_object_unref(pixbuf_new);
194 pixbuf_new = gdk_pixbuf_scale_simple(image_buffer, image_width*zoom, image_height*zoom,
195 GDK_INTERP_BILINEAR);
196 gtk_image_set_from_pixbuf((GtkImage*) lookup_widget(cropper_window, "image_area"), pixbuf_new);
197 }
199 void
200 on_zoom_in_button_clicked(GtkObject* object, gpointer user_data)
201 {
202 zoom *= 1 + inc;
203 set_zoom();
204 }
206 void
207 on_zoom_out_button_clicked(GtkObject* object, gpointer user_data)
208 {
209 zoom *= 1 - inc;
210 set_zoom();
211 }
213 void
214 on_zoom_100_button_clicked(GtkObject* object, gpointer user_data)
215 {
216 zoom = 1.0;
217 set_zoom();
218 }
220 void
221 on_zoom_fit_button_clicked(GtkObject* object, gpointer user_data)
222 {
223 int w, h;
224 float zw, zh;
225 GtkWidget* image_a;
227 image_a = (GtkWidget*) lookup_widget(cropper_window, "image_area");
228 gdk_drawable_get_size(image_a->window, &w, &h);
230 zw = w*1.0 / image_width;
231 zh = h*1.0 / image_height;
233 zoom = (zw < zh) ? zw : zh;
234 set_zoom();
235 }
243 void
244 crop(void)
245 {
246 char crop_call[256];
248 sprintf(crop_call, "echo \"convert -crop %ix%i+%i+%i %s cropped_%s\"",
249 gtk_spin_button_get_value_as_int((GtkSpinButton*) lookup_widget(cropper_window,
250 "crop_width_spinbutton")),
251 gtk_spin_button_get_value_as_int((GtkSpinButton*) lookup_widget(cropper_window,
252 "crop_height_spinbutton")),
253 gtk_spin_button_get_value_as_int((GtkSpinButton*) lookup_widget(cropper_window,
254 "crop_x_spinbutton")),
255 gtk_spin_button_get_value_as_int((GtkSpinButton*) lookup_widget(cropper_window,
256 "crop_y_spinbutton")),
257 image_filename,
258 image_filename
259 );
260 system(crop_call);
261 gtk_main_quit();
262 }
265 void
266 on_cropper_window_create(GtkObject* object, gpointer user_data)
267 {
268 image_width = gdk_pixbuf_get_width(image_buffer);
269 image_height = gdk_pixbuf_get_height(image_buffer);
271 /*
272 image_buffer = gdk_pixbuf_new_from_file(image_filename, NULL);
273 image_area = gtk_image_new_from_pixbuf(image_buffer);
275 int w, h;
276 GtkWidget* image_a;
278 image_a = (GtkWidget*) lookup_widget(cropper_window, "image_area");
279 gdk_drawable_get_size(image_a->window, &w, &h);
281 image_width = w - 200;
282 image_height = h - 150;
283 set_zoom();
284 */
285 }
287 void
288 on_cropper_window_destroy(GtkObject* object, gpointer user_data)
289 {
290 gtk_main_quit();
291 }
296 gboolean
297 on_key_press(GtkWidget* window, GdkEventKey* pKey, gpointer userdata)
298 {
299 if (pKey->type != GDK_KEY_PRESS) {
300 return FALSE;
301 }
302 switch (pKey->keyval) {
303 case GDK_q:
304 gtk_main_quit();
305 break;
306 case GDK_Return:
307 crop();
308 break;
309 case GDK_plus:
310 on_zoom_in_button_clicked(NULL, userdata);
311 break;
312 case GDK_minus:
313 on_zoom_out_button_clicked(NULL, userdata);
314 break;
315 case GDK_0:
316 on_zoom_100_button_clicked(NULL, userdata);
317 break;
318 case GDK_f:
319 on_zoom_fit_button_clicked(NULL, userdata);
320 break;
321 }
322 return TRUE;
323 }
332 int
333 main(int argc, char* argv[])
334 {
335 /* commandline option handling */
336 if (argc != 2) {
337 g_print("cropper -- a crop frontend to convert\n");
338 g_print("usage: cropper IMAGE\n");
339 return 1;
340 }
342 image_filename = argv[1];
343 gtk_init(&argc, &argv);
345 cropper_window = create_cropper_window();
346 gtk_widget_show(cropper_window);
347 gtk_main();
349 return 0;
350 }