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
|