cropper

annotate cropper.c @ 18:9d6e8105b145

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