1 /* ______ ___ ___
2 * /\ _ \ /\_ \ /\_ \
3 * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
5 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
6 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7 * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8 * /\____/
9 * \_/__/
10 *
11 * Grabber plugin for the grab-from-grid and autocrop functions.
12 *
13 * By Shawn Hargreaves.
14 *
15 * See readme.txt for copyright information.
16 */
17
18
19 #include <stdio.h>
20 #include <string.h>
21
22 #include "allegro.h"
23 #include "../datedit.h"
24
25
26
27 static int gg_text_proc(int msg, DIALOG *d, int c);
28 static int gg_edit_proc(int msg, DIALOG *d, int c);
29
30
31
32 static void *added_item[1024];
33 static int added_count;
34
35
36
37 /* helper for cropping bitmaps */
crop_bitmap(BITMAP * bmp,int * tx,int * ty)38 static BITMAP *crop_bitmap(BITMAP *bmp, int *tx, int *ty)
39 {
40 int tw, th, i, j, c;
41 int changed = FALSE;
42
43 *tx = 0;
44 *ty = 0;
45 tw = bmp->w;
46 th = bmp->h;
47
48 if ((tw > 0) && (th > 0)) {
49 c = getpixel(bmp, 0, 0);
50
51 for (j=*ty; j<(*ty)+th; j++) { /* top of image */
52 for (i=*tx; i<(*tx)+tw; i++) {
53 if (getpixel(bmp, i, j) != c)
54 goto finishedtop;
55 }
56 (*ty)++;
57 th--;
58 changed = TRUE;
59 }
60
61 finishedtop:
62
63 for (j=(*ty)+th-1; j>*ty; j--) { /* bottom of image */
64 for (i=*tx; i<(*tx)+tw; i++) {
65 if (getpixel(bmp, i, j) != c)
66 goto finishedbottom;
67 }
68 th--;
69 changed = TRUE;
70 }
71
72 finishedbottom:
73
74 for (j=*tx; j<*(tx)+tw; j++) { /* left of image */
75 for (i=*ty; i<(*ty)+th; i++) {
76 if (getpixel(bmp, j, i) != c)
77 goto finishedleft;
78 }
79 (*tx)++;
80 tw--;
81 changed = TRUE;
82 }
83
84 finishedleft:
85
86 for (j=*(tx)+tw-1; j>*tx; j--) { /* right of image */
87 for (i=*ty; i<(*ty)+th; i++) {
88 if (getpixel(bmp, j, i) != c)
89 goto finishedright;
90 }
91 tw--;
92 changed = TRUE;
93 }
94
95 finishedright:
96 ;
97 }
98
99 if ((tw != 0) && (th != 0) && (changed)) {
100 BITMAP *b2 = create_bitmap_ex(bitmap_color_depth(bmp), tw, th);
101 clear_to_color(b2, b2->vtable->mask_color);
102 blit(bmp, b2, *tx, *ty, 0, 0, tw, th);
103 destroy_bitmap(bmp);
104 return b2;
105 }
106 else
107 return bmp;
108 }
109
110
111
112 /* worker function for counting bitmap objects */
do_bitmap_check(DATAFILE * dat,int * param,int param2)113 static int do_bitmap_check(DATAFILE *dat, int *param, int param2)
114 {
115 if ((dat->type == DAT_BITMAP) || (dat->type == DAT_RLE_SPRITE) ||
116 (dat->type == DAT_C_SPRITE) || (dat->type == DAT_XC_SPRITE))
117 (*param)++;
118
119 return D_O_K;
120 }
121
122
123
124 /* checks whether our grab-from-grid command is allowed at the moment */
griddler_query(int popup)125 static int griddler_query(int popup)
126 {
127 DATAFILE *dat;
128 AL_CONST char *s;
129
130 if (popup) {
131 dat = grabber_single_selection();
132
133 if (!dat)
134 return FALSE;
135
136 if ((dat->type != DAT_BITMAP) && (dat->type != DAT_RLE_SPRITE) &&
137 (dat->type != DAT_C_SPRITE) && (dat->type != DAT_XC_SPRITE))
138 return FALSE;
139
140 s = get_datafile_property(dat, DAT_NAME);
141
142 if ((s[0]) && (uisdigit(s[strlen(s)-1])))
143 return TRUE;
144 else
145 return FALSE;
146 }
147
148 return TRUE;
149 }
150
151
152
153 /* checks whether a bitmap contains any data */
bitmap_is_empty(BITMAP * bmp)154 static int bitmap_is_empty(BITMAP *bmp)
155 {
156 int x, y;
157 int c = getpixel(bmp, 0, 0);
158
159 for (y=0; y<bmp->h; y++)
160 for (x=0; x<bmp->w; x++)
161 if (getpixel(bmp, x, y) != c)
162 return FALSE;
163
164 return TRUE;
165 }
166
167
168
169 /* helper for grabbing images from a grid */
griddlit(DATAFILE ** parent,AL_CONST char * name,int c,int type,int skipempty,int autocrop,int depth,int x,int y,int w,int h)170 static void *griddlit(DATAFILE **parent, AL_CONST char *name, int c, int type, int skipempty, int autocrop, int depth, int x, int y, int w, int h)
171 {
172 DATAFILE *dat;
173 BITMAP *bmp;
174 void *v;
175 char buf[256];
176 RGB tmprgb = datedit_current_palette[0];
177 int tx = 0, ty = 0;
178
179 if ((type == DAT_RLE_SPRITE) || (type == DAT_C_SPRITE) || (type == DAT_XC_SPRITE)) {
180 datedit_current_palette[0].r = 63;
181 datedit_current_palette[0].g = 0;
182 datedit_current_palette[0].b = 63;
183 }
184 select_palette(datedit_current_palette);
185
186 bmp = create_bitmap_ex(depth, w, h);
187 clear_to_color(bmp, bmp->vtable->mask_color);
188 blit(grabber_graphic, bmp, x, y, 0, 0, w, h);
189
190 unselect_palette();
191 datedit_current_palette[0] = tmprgb;
192
193 if ((skipempty) && (bitmap_is_empty(bmp))) {
194 destroy_bitmap(bmp);
195 return NULL;
196 }
197
198 if (autocrop)
199 bmp = crop_bitmap(bmp, &tx, &ty);
200
201 if (type == DAT_RLE_SPRITE) {
202 v = get_rle_sprite(bmp);
203 destroy_bitmap(bmp);
204 }
205 else
206 v = bmp;
207
208 sprintf(buf, "%s%03d", name, c);
209
210 *parent = datedit_insert(*parent, &dat, buf, type, v, 0);
211
212 sprintf(buf, "%d", x);
213 datedit_set_property(dat, DAT_XPOS, buf);
214
215 sprintf(buf, "%d", y);
216 datedit_set_property(dat, DAT_YPOS, buf);
217
218 sprintf(buf, "%d", w);
219 datedit_set_property(dat, DAT_XSIZ, buf);
220
221 sprintf(buf, "%d", h);
222 datedit_set_property(dat, DAT_YSIZ, buf);
223
224 if (tx || ty) {
225 sprintf(buf, "%d", tx);
226 datedit_set_property(dat, DAT_XCRP, buf);
227
228 sprintf(buf, "%d", ty);
229 datedit_set_property(dat, DAT_YCRP, buf);
230 }
231
232 datedit_set_property(dat, DAT_ORIG, grabber_graphic_origin);
233 datedit_set_property(dat, DAT_DATE, grabber_graphic_date);
234
235 datedit_sort_properties(dat->prop);
236
237 if (added_count < (int)(sizeof(added_item)/sizeof(added_item[0])))
238 added_item[added_count++] = v;
239
240 return v;
241 }
242
243
244
245 /* grabs images from a grid, using boxes of color #255 */
box_griddle(DATAFILE ** parent,AL_CONST char * name,int type,int skipempty,int autocrop,int depth)246 static void *box_griddle(DATAFILE **parent, AL_CONST char *name, int type, int skipempty, int autocrop, int depth)
247 {
248 void *ret = NULL;
249 void *item;
250 int x, y, w, h;
251 int c = 0;
252
253 x = 0;
254 y = 0;
255
256 datedit_find_character(grabber_graphic, &x, &y, &w, &h);
257
258 while ((w > 0) && (h > 0)) {
259 item = griddlit(parent, name, c, type, skipempty, autocrop, depth, x+1, y+1, w, h);
260 if (item) {
261 c++;
262 if (!ret)
263 ret = item;
264 }
265
266 x += w;
267 datedit_find_character(grabber_graphic, &x, &y, &w, &h);
268 }
269
270 return ret;
271 }
272
273
274
275 /* grabs images from a regular grid */
grid_griddle(DATAFILE ** parent,AL_CONST char * name,int type,int skipempty,int autocrop,int depth,int xgrid,int ygrid)276 static void *grid_griddle(DATAFILE **parent, AL_CONST char *name, int type, int skipempty, int autocrop, int depth, int xgrid, int ygrid)
277 {
278 void *ret = NULL;
279 void *item;
280 int x, y;
281 int c = 0;
282
283 for (y=0; y+ygrid<=grabber_graphic->h; y+=ygrid) {
284 for (x=0; x+xgrid<=grabber_graphic->w; x+=xgrid) {
285 item = griddlit(parent, name, c, type, skipempty, autocrop, depth, x, y, xgrid, ygrid);
286 if (item) {
287 c++;
288 if (!ret)
289 ret = item;
290 }
291 }
292 }
293
294 return ret;
295 }
296
297
298
299 static char griddle_xgrid[8] = "32";
300 static char griddle_ygrid[8] = "32";
301 static char griddle_name[256] = "";
302
303
304
305 /* dialog callback for retrieving the contents of the object type list */
typelist_getter(int index,int * list_size)306 static AL_CONST char *typelist_getter(int index, int *list_size)
307 {
308 static char *str[] =
309 {
310 "Bitmap",
311 "RLE Sprite",
312 "Compiled Sprite",
313 "Mode-X Compiled Sprite"
314 };
315
316 if (index < 0) {
317 if (list_size)
318 *list_size = 4;
319 return NULL;
320 }
321
322 return str[index];
323 }
324
325
326
327 /* dialog callback for retrieving the contents of the color depth list */
depthlist_getter(int index,int * list_size)328 static AL_CONST char *depthlist_getter(int index, int *list_size)
329 {
330 static char *str[] =
331 {
332 "256 color palette",
333 "15 bit hicolor",
334 "16 bit hicolor",
335 "24 bit truecolor",
336 "32 bit truecolor"
337 };
338
339 if (index < 0) {
340 if (list_size)
341 *list_size = 5;
342 return NULL;
343 }
344
345 return str[index];
346 }
347
348
349
350 static DIALOG griddle_dlg[] =
351 {
352 /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) (dp2) (dp3) */
353 { d_shadow_box_proc, 0, 0, 277, 305, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
354 { d_ctext_proc, 138, 8, 0, 0, 0, 0, 0, 0, 0, 0, "Grab from Grid", NULL, NULL },
355 { d_radio_proc, 16, 32, 121, 13, 0, 0, 0, D_SELECTED, 0, 0, "Use col #255", NULL, NULL },
356 { d_radio_proc, 16, 56, 121, 13, 0, 0, 0, 0, 0, 0, "Regular grid", NULL, NULL },
357 { gg_text_proc, 160, 58, 0, 0, 0, 0, 0, 0, 0, 0, "X-grid:", NULL, NULL },
358 { gg_edit_proc, 224, 58, 40, 8, 0, 0, 0, 0, 4, 0, griddle_xgrid, NULL, NULL },
359 { gg_text_proc, 160, 80, 0, 0, 0, 0, 0, 0, 0, 0, "Y-grid:", NULL, NULL },
360 { gg_edit_proc, 224, 82, 40, 8, 0, 0, 0, 0, 4, 0, griddle_ygrid, NULL, NULL },
361 { d_check_proc, 16, 82, 123, 13, 0, 0, 0, 0, 0, 0, "Skip empties:", NULL, NULL },
362 { d_check_proc, 16, 106, 91, 13, 0, 0, 0, 0, 0, 0, "Autocrop:", NULL, NULL },
363 { d_text_proc, 16, 138, 0, 0, 0, 0, 0, 0, 0, 0, "Name:", NULL, NULL },
364 { d_edit_proc, 64, 138, 204, 8, 0, 0, 0, 0, 255, 0, griddle_name, NULL, NULL },
365 { d_text_proc, 16, 160, 0, 0, 0, 0, 0, 0, 0, 0, "Type:", NULL, NULL },
366 { d_list_proc, 64, 160, 197, 36, 0, 0, 0, 0, 0, 0, (void*)typelist_getter, NULL, NULL },
367 { d_text_proc, 16, 208, 0, 0, 0, 0, 0, 0, 0, 0, "Cols:", NULL, NULL },
368 { d_list_proc, 64, 208, 197, 44, 0, 0, 0, 0, 0, 0, (void*)depthlist_getter, NULL, NULL },
369 { d_button_proc, 50, 272, 81, 17, 0, 0, 13, D_EXIT, 0, 0, "OK", NULL, NULL },
370 { d_button_proc, 146, 272, 81, 17, 0, 0, 27, D_EXIT, 0, 0, "Cancel", NULL, NULL },
371 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
372 };
373
374
375 #define GRIDDLE_DLG_BOXES 2
376 #define GRIDDLE_DLG_GRID 3
377 #define GRIDDLE_DLG_XGRID 5
378 #define GRIDDLE_DLG_YGRID 7
379 #define GRIDDLE_DLG_EMPTIES 8
380 #define GRIDDLE_DLG_AUTOCROP 9
381 #define GRIDDLE_DLG_NAME 11
382 #define GRIDDLE_DLG_TYPE 13
383 #define GRIDDLE_DLG_DEPTH 15
384 #define GRIDDLE_DLG_OK 16
385 #define GRIDDLE_DLG_CANCEL 17
386
387
388
389 /* wrapper for d_text_proc, that greys out when invalid */
gg_text_proc(int msg,DIALOG * d,int c)390 static int gg_text_proc(int msg, DIALOG *d, int c)
391 {
392 if (msg == MSG_IDLE) {
393 int valid = (griddle_dlg[GRIDDLE_DLG_BOXES].flags & D_SELECTED) ? 0 : 1;
394 int enabled = (d->flags & D_DISABLED) ? 0 : 1;
395
396 if (valid != enabled) {
397 if (valid)
398 d->flags &= ~D_DISABLED;
399 else
400 d->flags |= D_DISABLED;
401
402 object_message(d, MSG_DRAW, 0);
403 }
404
405 return D_O_K;
406 }
407 else
408 return d_text_proc(msg, d, c);
409 }
410
411
412
413 /* wrapper for d_edit_proc, that greys out when invalid */
gg_edit_proc(int msg,DIALOG * d,int c)414 static int gg_edit_proc(int msg, DIALOG *d, int c)
415 {
416 if (msg == MSG_IDLE) {
417 int valid = (griddle_dlg[GRIDDLE_DLG_BOXES].flags & D_SELECTED) ? 0 : 1;
418 int enabled = (d->flags & D_DISABLED) ? 0 : 1;
419
420 if (valid != enabled) {
421 if (valid)
422 d->flags &= ~D_DISABLED;
423 else
424 d->flags |= D_DISABLED;
425
426 object_message(d, MSG_DRAW, 0);
427 }
428
429 return D_O_K;
430 }
431 else
432 return d_edit_proc(msg, d, c);
433 }
434
435
436
437 /* checks whether an object name matches the grid grab base name */
grid_name_matches(AL_CONST char * gn,AL_CONST char * n)438 static int grid_name_matches(AL_CONST char *gn, AL_CONST char *n)
439 {
440 AL_CONST char *s;
441
442 if (strncmp(gn, n, strlen(gn)) != 0)
443 return FALSE;
444
445 s = n + strlen(gn);
446 if (*s == 0)
447 return FALSE;
448
449 while (*s) {
450 if (!uisdigit(*s))
451 return FALSE;
452 s++;
453 }
454
455 return TRUE;
456 }
457
458
459
460 /* handle the griddle command */
griddler(void)461 static int griddler(void)
462 {
463 DATAFILE *dat;
464 DATAFILE **parent;
465 void *selitem;
466 char *s;
467 int c;
468 int xgrid, ygrid;
469 int done, type, skipempty, autocrop;
470 int depth = 8;
471
472 if (!grabber_graphic) {
473 alert("You must read in a bitmap file",
474 "before you can grab data from it",
475 NULL, "OK", NULL, 13, 0);
476 return D_O_K;
477 }
478
479 grabber_get_selection_info(&dat, &parent);
480
481 if (!dat) {
482 griddle_name[0] = 0;
483 depth = bitmap_color_depth(grabber_graphic);
484 }
485 else {
486 strcpy(griddle_name, get_datafile_property(dat, DAT_NAME));
487 s = griddle_name + strlen(griddle_name) - 1;
488 while ((s >= griddle_name) && (uisdigit(*s))) {
489 *s = 0;
490 s--;
491 }
492
493 if (dat->type == DAT_BITMAP) {
494 griddle_dlg[GRIDDLE_DLG_TYPE].d1 = 0;
495 depth = bitmap_color_depth(dat->dat);
496 }
497 else if (dat->type == DAT_RLE_SPRITE) {
498 griddle_dlg[GRIDDLE_DLG_TYPE].d1 = 1;
499 depth = ((RLE_SPRITE *)dat->dat)->color_depth;
500 }
501 else if (dat->type == DAT_C_SPRITE) {
502 griddle_dlg[GRIDDLE_DLG_TYPE].d1 = 2;
503 depth = bitmap_color_depth(dat->dat);
504 }
505 else if (dat->type == DAT_XC_SPRITE) {
506 griddle_dlg[GRIDDLE_DLG_TYPE].d1 = 3;
507 depth = 8;
508 }
509 }
510
511 if (depth == 8)
512 griddle_dlg[GRIDDLE_DLG_DEPTH].d1 = 0;
513 else if (depth == 15)
514 griddle_dlg[GRIDDLE_DLG_DEPTH].d1 = 1;
515 else if (depth == 16)
516 griddle_dlg[GRIDDLE_DLG_DEPTH].d1 = 2;
517 else if (depth == 24)
518 griddle_dlg[GRIDDLE_DLG_DEPTH].d1 = 3;
519 else if (depth == 32)
520 griddle_dlg[GRIDDLE_DLG_DEPTH].d1 = 4;
521
522 centre_dialog(griddle_dlg);
523 set_dialog_color(griddle_dlg, gui_fg_color, gui_bg_color);
524
525 if (do_dialog(griddle_dlg, GRIDDLE_DLG_NAME) == GRIDDLE_DLG_CANCEL)
526 return D_REDRAW;
527
528 grabber_sel_palette(grabber_palette);
529
530 do {
531 done = TRUE;
532
533 for (c=0; (*parent)[c].type != DAT_END; c++) {
534 if (grid_name_matches(griddle_name, get_datafile_property((*parent)+c, DAT_NAME))) {
535 *parent = datedit_delete(*parent, c);
536 done = FALSE;
537 break;
538 }
539 }
540 } while (!done);
541
542 switch (griddle_dlg[GRIDDLE_DLG_TYPE].d1) {
543
544 case 0:
545 default:
546 type = DAT_BITMAP;
547 break;
548
549 case 1:
550 type = DAT_RLE_SPRITE;
551 break;
552
553 case 2:
554 type = DAT_C_SPRITE;
555 break;
556
557 case 3:
558 type = DAT_XC_SPRITE;
559 break;
560 }
561
562 switch (griddle_dlg[GRIDDLE_DLG_DEPTH].d1) {
563
564 case 0:
565 default:
566 depth = 8;
567 break;
568
569 case 1:
570 depth = 15;
571 break;
572
573 case 2:
574 depth = 16;
575 break;
576
577 case 3:
578 depth = 24;
579 break;
580
581 case 4:
582 depth = 32;
583 break;
584 }
585
586 skipempty = griddle_dlg[GRIDDLE_DLG_EMPTIES].flags & D_SELECTED;
587 autocrop = griddle_dlg[GRIDDLE_DLG_AUTOCROP].flags & D_SELECTED;
588
589 added_count = 0;
590
591 if (griddle_dlg[GRIDDLE_DLG_BOXES].flags & D_SELECTED)
592 selitem = box_griddle(parent, griddle_name, type, skipempty, autocrop, depth);
593 else {
594 xgrid = CLAMP(1, atoi(griddle_xgrid), 0xFFFF);
595 ygrid = CLAMP(1, atoi(griddle_ygrid), 0xFFFF);
596 selitem = grid_griddle(parent, griddle_name, type, skipempty, autocrop, depth, xgrid, ygrid);
597 }
598
599 datedit_sort_datafile(*parent);
600 grabber_rebuild_list(selitem, TRUE);
601 grabber_select_property(DAT_NAME);
602
603 for (c=0; c<added_count; c++)
604 grabber_set_selection(added_item[c]);
605
606 if (selitem) {
607 grabber_sel_palette(grabber_palette);
608 grabber_modified(TRUE);
609 }
610 else
611 alert("No grid found - nothing grabbed!", NULL, NULL, "Hmm...", NULL, 13, 0);
612
613 set_config_string("grabber", "griddle_xgrid", griddle_xgrid);
614 set_config_string("grabber", "griddle_ygrid", griddle_ygrid);
615
616 if (griddle_dlg[GRIDDLE_DLG_BOXES].flags & D_SELECTED)
617 set_config_string("grabber", "griddle_mode", "boxes");
618 else
619 set_config_string("grabber", "griddle_mode", "grid");
620
621 if (griddle_dlg[GRIDDLE_DLG_EMPTIES].flags & D_SELECTED)
622 set_config_string("grabber", "griddle_empties", "y");
623 else
624 set_config_string("grabber", "griddle_empties", "n");
625
626 if (griddle_dlg[GRIDDLE_DLG_AUTOCROP].flags & D_SELECTED)
627 set_config_string("grabber", "griddle_autocrop", "y");
628 else
629 set_config_string("grabber", "griddle_autocrop", "n");
630
631 set_config_int("grabber", "griddle_type", griddle_dlg[GRIDDLE_DLG_TYPE].d1);
632
633 return D_REDRAW;
634 }
635
636
637
638 /* worker function for cropping an image */
do_autocropper(DATAFILE * dat,int * param,int param2)639 static int do_autocropper(DATAFILE *dat, int *param, int param2)
640 {
641 BITMAP *bmp;
642 RLE_SPRITE *spr;
643 char buf[256];
644 int tx, ty;
645
646 if ((dat->type != DAT_BITMAP) && (dat->type != DAT_RLE_SPRITE) &&
647 (dat->type != DAT_C_SPRITE) && (dat->type != DAT_XC_SPRITE)) {
648 (*param)++;
649 return D_O_K;
650 }
651
652 if (dat->type == DAT_RLE_SPRITE) {
653 spr = (RLE_SPRITE *)dat->dat;
654 bmp = create_bitmap_ex(spr->color_depth, spr->w, spr->h);
655 clear_to_color(bmp, bmp->vtable->mask_color);
656 draw_rle_sprite(bmp, spr, 0, 0);
657 destroy_rle_sprite(spr);
658 bmp = crop_bitmap(bmp, &tx, &ty);
659 dat->dat = get_rle_sprite(bmp);
660 destroy_bitmap(bmp);
661 }
662 else
663 dat->dat = crop_bitmap((BITMAP *)dat->dat, &tx, &ty);
664
665 if (tx || ty) {
666 sprintf(buf, "%d", tx);
667 datedit_set_property(dat, DAT_XCRP, buf);
668
669 sprintf(buf, "%d", ty);
670 datedit_set_property(dat, DAT_YCRP, buf);
671 }
672
673 grabber_modified(TRUE);
674
675 return D_REDRAW;
676 }
677
678
679
680 /* checks whether our autocrop command is allowed at the moment */
autocrop_query(int popup)681 static int autocrop_query(int popup)
682 {
683 int n, p;
684
685 if (popup) {
686 p = 0;
687 grabber_foreach_selection(do_bitmap_check, &n, &p, 0);
688 return (p > 0);
689 }
690
691 return TRUE;
692 }
693
694
695
696 /* menu hook for the autocrop command */
autocrop(void)697 static int autocrop(void)
698 {
699 char buf[80];
700 int ret, n;
701 int p = 0;
702
703 ret = grabber_foreach_selection(do_autocropper, &n, &p, 0);
704
705 if (n <= 0) {
706 alert ("Nothing to crop!", NULL, NULL, "OK", NULL, 13, 0);
707 }
708 else if (p > 0) {
709 sprintf(buf, "%d non-bitmap object%s ignored", p, (p==1) ? " was" : "s were");
710 alert(buf, NULL, NULL, "OK", NULL, 13, 0);
711 }
712
713 return ret;
714 }
715
716
717
718 /* initialisation code for the grab-from-grid plugin */
datgrid_init(void)719 void datgrid_init(void)
720 {
721 int i;
722
723 if (screen) {
724 if (SCREEN_H < 400) {
725 griddle_dlg[0].h = griddle_dlg[0].h * 2/3;
726 for (i=1; griddle_dlg[i].proc; i++) {
727 griddle_dlg[i].y = griddle_dlg[i].y * 2/3;
728 if (griddle_dlg[i].h > 32)
729 griddle_dlg[i].h -= 8;
730 }
731 }
732 }
733
734 sprintf(griddle_xgrid, "%d", get_config_int("grabber", "griddle_xgrid", 32));
735 sprintf(griddle_ygrid, "%d", get_config_int("grabber", "griddle_ygrid", 32));
736
737 if (stricmp(get_config_string("grabber", "griddle_mode", ""), "grid") == 0) {
738 griddle_dlg[GRIDDLE_DLG_BOXES].flags &= ~D_SELECTED;
739 griddle_dlg[GRIDDLE_DLG_GRID].flags |= D_SELECTED;
740 }
741 else {
742 griddle_dlg[GRIDDLE_DLG_BOXES].flags |= D_SELECTED;
743 griddle_dlg[GRIDDLE_DLG_GRID].flags &= ~D_SELECTED;
744 }
745
746 if (strpbrk(get_config_string("grabber", "griddle_empties", ""), "yY1"))
747 griddle_dlg[GRIDDLE_DLG_EMPTIES].flags |= D_SELECTED;
748 else
749 griddle_dlg[GRIDDLE_DLG_EMPTIES].flags &= ~D_SELECTED;
750
751 if (strpbrk(get_config_string("grabber", "griddle_autocrop", ""), "yY1"))
752 griddle_dlg[GRIDDLE_DLG_AUTOCROP].flags |= D_SELECTED;
753 else
754 griddle_dlg[GRIDDLE_DLG_AUTOCROP].flags &= ~D_SELECTED;
755
756 griddle_dlg[GRIDDLE_DLG_TYPE].d1 = get_config_int("grabber", "griddle_type", 0);
757 }
758
759
760
761 /* hook ourselves into the grabber menu system */
762 static MENU griddler_menu =
763 {
764 "Grab from Grid",
765 griddler,
766 NULL,
767 0,
768 NULL
769 };
770
771
772
773 DATEDIT_MENU_INFO datgrid_griddler_menu =
774 {
775 &griddler_menu,
776 griddler_query,
777 DATEDIT_MENU_FILE | DATEDIT_MENU_POPUP,
778 0,
779 "XPOS;YPOS;XSIZ;YSIZ"
780 };
781
782
783
784 static MENU autocrop_menu =
785 {
786 "Autocrop",
787 autocrop,
788 NULL,
789 0,
790 NULL
791 };
792
793
794
795 DATEDIT_MENU_INFO datgrid_autocrop_menu =
796 {
797 &autocrop_menu,
798 autocrop_query,
799 DATEDIT_MENU_OBJECT | DATEDIT_MENU_POPUP,
800 0,
801 "XCRP;YCRP"
802 };
803
804