From 17f2d5444658aa487f875250c6f561cae49ee605 Mon Sep 17 00:00:00 2001
From: Ivica Ico Bukvic <ico@vt.edu>
Date: Sat, 17 Aug 2013 01:10:21 -0400
Subject: [PATCH] fixed a number of small bugs including a segfault, inability
 to open local files, adapted code to reflect improved path searching, made
 image draw gray square when no image is available, reworked the way image
 allows for spilling beyond the GOP area by adding a second float flag,
 updated help file to reflect new features

---
 externals/ggee/gui/image-help.pd |  49 ++++++++---
 externals/ggee/gui/image.c       | 139 ++++++++++++++++++++++---------
 2 files changed, 140 insertions(+), 48 deletions(-)

diff --git a/externals/ggee/gui/image-help.pd b/externals/ggee/gui/image-help.pd
index 80e0acdc3..cfc53152d 100644
--- a/externals/ggee/gui/image-help.pd
+++ b/externals/ggee/gui/image-help.pd
@@ -1,25 +1,54 @@
-#N canvas 0 26 462 397 10;
-#X obj 213 273 image /home/ico/Downloads/PureData/pure-data/externals/ggee/gui/logo100.gif
+#N canvas 0 26 462 618 10;
+#X obj 74 489 ggee/image @pd_extra/ggee/logo100.gif
 ;
-#X text 19 18 Incorporate images. This is instantiated with;
-#X text 19 31 [image logo100.gif];
-#X msg 179 179 open \$1;
-#X obj 179 135 bng 15 250 50 0 empty empty empty 0 -6 0 10 -4034 -1
+#X text 26 12 Incorporate images. This is instantiated with;
+#X text 26 25 [image logo100.gif];
+#X msg 40 395 open \$1;
+#X obj 40 351 bng 15 250 50 0 empty empty empty 0 -6 0 10 -4034 -1
 -1;
-#X obj 179 156 openpanel;
+#X obj 40 372 openpanel;
 #N canvas 369 218 396 195 META 0;
 #X text 12 125 HELP_PATCH_AUTHORS "pd meta" information added by Jonathan
 Wilkes for Pd version 0.42.;
 #X text 12 25 LICENSE Tcl/Tk;
 #X text 12 5 KEYWORDS control GUI;
 #X text 12 45 DESCRIPTION display an image;
-#X text 12 65 INLET_0 open size;
 #X text 12 85 OUTLET_0 bang;
 #X text 12 105 AUTHOR Ivica Ico Bukvic \, based on Guenter Geiger's
 image;
-#X restore 412 376 pd META;
-#X text 19 64 [image] works with .gif \, .ppm \, .pgm and .png image
+#X text 12 65 INLET_0 open gopspill;
+#X restore 405 590 pd META;
+#X obj 162 490 ggee/image @pd_extra/ggee/logo100.gif;
+#X obj 155 348 loadbang;
+#X msg 155 371 1;
+#X msg 155 395 gopspill \$1;
+#X floatatom 184 371 5 0 0 0 - - -;
+#X obj 252 448 ggee/image ;
+#X msg 245 395 open \$1;
+#X obj 245 351 bng 15 250 50 0 empty empty empty 0 -6 0 10 -4034 -1
+-1;
+#X obj 245 372 openpanel;
+#X text 26 48 [image] works with .gif \, .ppm \, .pgm and .png image
 formats only.;
+#X text 263 425 this is how an empty imagelooks like when createdwithout
+any parameters;
+#X text 27 83 Pd-L2Ork version of [image] also has a special feature
+that allows its reported rectangle to be smaller \, so it can be used
+as a decoration for a graph-on-parent abstraction that may potentially
+spill beyond the grap-on-parent rectangle (as is the case with K12
+mode). To invoke this mode \, pass a "gopspill 0/1" message into the
+object or create it by giving it an optional argument \, 0=off(default)
+\, 1=on. Filename is always first optional argument and the float argument
+second. In the absence of a symbol (string) filename \, the float value
+will be treated as the gopspill argument. For instance:[image logo100.gif
+1][image logo100.gif 0] is synonymous to [image logo100.gif];
 #X connect 3 0 0 0;
 #X connect 4 0 5 0;
 #X connect 5 0 3 0;
+#X connect 8 0 9 0;
+#X connect 9 0 10 0;
+#X connect 10 0 7 0;
+#X connect 11 0 10 0;
+#X connect 13 0 12 0;
+#X connect 14 0 15 0;
+#X connect 15 0 13 0;
diff --git a/externals/ggee/gui/image.c b/externals/ggee/gui/image.c
index d22852163..87db3f6da 100644
--- a/externals/ggee/gui/image.c
+++ b/externals/ggee/gui/image.c
@@ -21,6 +21,7 @@ typedef struct _image
 	int x_height;
 	int x_img_width;
 	int x_img_height;
+	int x_gop_spill;
 	t_symbol*  x_fname;
 	t_symbol* receive;
 	//t_symbol* send;
@@ -29,22 +30,34 @@ typedef struct _image
 /* widget helper functions */
 
 void image_doopen(t_image* x) {
+	t_glist *glist = glist_getcanvas(x->x_glist);
 	if (strlen(x->x_fname->s_name) != 0) {
-		char fname[MAXPDSTRING];
+		char fname[FILENAME_MAX];
 		canvas_makefilename(glist_getcanvas(x->x_glist), x->x_fname->s_name,
-						fname, MAXPDSTRING);
-		
-		//check for sys path arguments and replace
-		char *new_fname = canvas_parse_sys_filename_args(x->x_fname->s_name);
-		strcpy(fname, new_fname);
-		freebytes(new_fname, strlen(new_fname));
-
+						fname, FILENAME_MAX);
+		fprintf(stderr,"post @ cooked name <%s>\n", fname);
+		sys_vgui(".x%x.c create rectangle \
+			%d %d %d %d -tags %xMT -outline black -fill gray\n",
+			glist_getcanvas(glist),
+			text_xpix(&x->x_obj, glist) - x->x_width/2,
+			text_ypix(&x->x_obj, glist) - x->x_height/2,
+			text_xpix(&x->x_obj, glist) + x->x_width/2,
+			text_ypix(&x->x_obj, glist) + x->x_height/2, x);
 		sys_vgui("catch {image delete $img%x}\n", x);
 		sys_vgui("set img%x [image create photo -file {%s}]\n", x, fname);
 		sys_vgui(".x%x.c itemconfigure %xS -image $img%x\n", 
-			   glist_getcanvas(x->x_glist),x,x);
+			   glist, x, x);
 		sys_vgui("pd [concat %s _imagesize [image width $img%x] [image height $img%x] \\;]\n",x->receive->s_name, x, x);
 	}
+	else {
+		sys_vgui(".x%x.c create rectangle \
+			%d %d %d %d -tags %xMT -outline black -fill gray\n",
+			glist_getcanvas(glist),
+			text_xpix(&x->x_obj, glist) - x->x_width/2,
+			text_ypix(&x->x_obj, glist) - x->x_height/2,
+			text_xpix(&x->x_obj, glist) + x->x_width/2,
+			text_ypix(&x->x_obj, glist) + x->x_height/2, x);
+	}
 }
 
 void image_drawme(t_image *x, t_glist *glist, int redraw)
@@ -52,6 +65,7 @@ void image_drawme(t_image *x, t_glist *glist, int redraw)
 	if (redraw) {
 		//first create blank image widget (in case we have no image to begin with)
 		//sys_vgui(".x%x.c itemconfigure %xS -image null\n", glist_getcanvas(glist));
+		sys_vgui("catch {.x%x.c delete %xMT}\n",glist_getcanvas(glist), x);
 		sys_vgui("catch {.x%lx.c delete %xS}\n", glist_getcanvas(glist),x);
 		sys_vgui(".x%x.c create image %d %d -tags %xS\n", 
 			glist_getcanvas(glist),text_xpix(&x->x_obj, glist), 
@@ -59,6 +73,11 @@ void image_drawme(t_image *x, t_glist *glist, int redraw)
 		image_doopen(x);
      }     
      else {
+		if (x->x_img_width + x->x_img_height == 0) {
+			sys_vgui(".x%x.c coords %xMT %d %d\n",
+				glist_getcanvas(glist), x,
+				text_xpix(&x->x_obj, glist), text_ypix(&x->x_obj, glist));
+		}
 		sys_vgui(".x%x.c coords %xS %d %d\n",
 			glist_getcanvas(glist), x,
 			text_xpix(&x->x_obj, glist), text_ypix(&x->x_obj, glist));
@@ -69,6 +88,7 @@ void image_drawme(t_image *x, t_glist *glist, int redraw)
 
 void image_erase(t_image* x,t_glist* glist)
 {
+	sys_vgui("catch {.x%x.c delete %xMT}\n",glist_getcanvas(glist), x);
 	sys_vgui("catch {.x%x.c delete %xS}\n",glist_getcanvas(glist), x);
 	sys_vgui("catch {image delete $img%x}\n", x);
 	sys_vgui("catch {.x%x.c delete %xSEL}\n",glist_getcanvas(glist), x);
@@ -86,8 +106,12 @@ static t_symbol *get_filename(t_int argc, t_atom *argv)
         strcpy(buf, fname->s_name);
         for(i = 1; i < argc; i++)
         {
-            strcat(buf, " ");
-            strcat(buf, atom_getsymbolarg(i, argc, argv)->s_name);
+			if (argv[i].a_type == A_SYMBOL) {
+		        strcat(buf, " ");
+		        strcat(buf, atom_getsymbolarg(i, argc, argv)->s_name);
+			} else {
+				break;
+			}
         }
         fname = gensym(buf);
     }
@@ -96,29 +120,23 @@ static t_symbol *get_filename(t_int argc, t_atom *argv)
 
 /* ------------------------ image widgetbehaviour----------------------------- */
 
-extern int sys_k12_mode;
-
 static void image_getrect(t_gobj *z, t_glist *glist,
     int *xp1, int *yp1, int *xp2, int *yp2)
 {
 	int width, height;
 	t_image* x = (t_image*)z;
 
-	if (!sys_k12_mode) {
+	if (!x->x_gop_spill && (x->x_img_width + x->x_img_height) >= 2) {
 		width = x->x_img_width;
-		height = x->x_img_height;
-		*xp1 = text_xpix(&x->x_obj, glist) - width/2;
-		*yp1 = text_ypix(&x->x_obj, glist) - height/2;
-		*xp2 = text_xpix(&x->x_obj, glist) + width/2;
-		*yp2 = text_ypix(&x->x_obj, glist) + height/2;	
+		height = x->x_img_height;	
 	} else {
 		width = x->x_width;
 		height = x->x_height;
-		*xp1 = text_xpix(&x->x_obj, glist) - width/2;
-		*yp1 = text_ypix(&x->x_obj, glist) - height/2;
-		*xp2 = text_xpix(&x->x_obj, glist) + width/2;
-		*yp2 = text_ypix(&x->x_obj, glist) + height/2;
 	}
+	*xp1 = text_xpix(&x->x_obj, glist) - width/2;
+	*yp1 = text_ypix(&x->x_obj, glist) - height/2;
+	*xp2 = text_xpix(&x->x_obj, glist) + width/2;
+	*yp2 = text_ypix(&x->x_obj, glist) + height/2;
 	//fprintf(stderr,"image_getrect %d %d %d %d\n", *xp1, *yp1, *xp2, *yp2);
 }
 
@@ -129,20 +147,28 @@ static void image_displace(t_gobj *z, t_glist *glist,
     t_image *x = (t_image *)z;
     x->x_obj.te_xpix += dx;
     x->x_obj.te_ypix += dy;
-	if (!sys_k12_mode)
+	if (!x->x_gop_spill && (x->x_img_width + x->x_img_height) >= 2){
 		sys_vgui(".x%x.c coords %xSEL %d %d %d %d\n",
 			glist_getcanvas(glist), x,
 			text_xpix(&x->x_obj, glist) - x->x_img_width/2,
 			text_ypix(&x->x_obj, glist) - x->x_img_height/2,
 			text_xpix(&x->x_obj, glist) + x->x_img_width/2,
 			text_ypix(&x->x_obj, glist) + x->x_img_height/2);
-	else
+	} else {
 		sys_vgui(".x%x.c coords %xSEL %d %d %d %d\n",
 			glist_getcanvas(glist), x,
 			text_xpix(&x->x_obj, glist) - x->x_width/2,
 			text_ypix(&x->x_obj, glist) - x->x_height/2,
 			text_xpix(&x->x_obj, glist) + x->x_width/2,
 			text_ypix(&x->x_obj, glist) + x->x_height/2);
+		if (x->x_img_width + x->x_img_height == 0)
+			sys_vgui(".x%x.c coords %xMT %d %d %d %d\n",
+				glist_getcanvas(glist), x,
+				text_xpix(&x->x_obj, glist) - x->x_width/2,
+				text_ypix(&x->x_obj, glist) - x->x_height/2,
+				text_xpix(&x->x_obj, glist) + x->x_width/2,
+				text_ypix(&x->x_obj, glist) + x->x_height/2);
+	}
 
     image_drawme(x, glist, 0);
     canvas_fixlinesfor(glist,(t_text*) x);
@@ -170,7 +196,7 @@ static void image_select(t_gobj *z, t_glist *glist, int state)
 	t_image *x = (t_image *)z;
 	if (state) {
 		if (glist_istoplevel(glist)) {
-			if (!sys_k12_mode)
+			if (!x->x_gop_spill && (x->x_img_width + x->x_img_height) >= 2)
 				sys_vgui(".x%x.c create rectangle \
 					%d %d %d %d -tags %xSEL -outline $select_color\n",
 					glist_getcanvas(glist),
@@ -189,6 +215,7 @@ static void image_select(t_gobj *z, t_glist *glist, int state)
 		}
 		//if (glist->gl_owner && !glist_istoplevel(glist))
 		sys_vgui(".x%x.c addtag selected withtag %xS\n", glist_getcanvas(glist), x);
+		sys_vgui(".x%x.c addtag selected withtag %xMT\n", glist_getcanvas(glist), x);
 		sys_vgui(".x%x.c addtag selected withtag %xSEL\n", glist_getcanvas(glist), x);
 	}
 	else {
@@ -196,15 +223,19 @@ static void image_select(t_gobj *z, t_glist *glist, int state)
 		glist_getcanvas(glist), x);
 		//if (glist->gl_owner && !glist_istoplevel(glist))
 		sys_vgui(".x%lx.c dtag %xS selected\n", glist_getcanvas(glist), x);
+		sys_vgui(".x%lx.c dtag %xMT selected\n", glist_getcanvas(glist), x);
 	}
 }
 
 
 static void image_activate(t_gobj *z, t_glist *glist, int state)
 {
-	/*t_text *x = (t_text *)z;
+	/*fprintf(stderr,"activate...\n");
+	t_text *x = (t_text *)z;
 	t_rtext *y = glist_findrtext(glist, x);
-	if (z->g_pd != gatom_class) rtext_activate(y, state);*/
+	rtext_activate(y, state);
+	t_image *i = (t_image *)z;
+	canvas_redraw(i->x_glist);*/
 }
 
 static void image_delete(t_gobj *z, t_glist *glist)
@@ -239,18 +270,18 @@ static void image_save(t_gobj *z, t_binbuf *b)
 
 t_widgetbehavior   image_widgetbehavior;
 
-void image_size(t_image* x,t_floatarg w,t_floatarg h) {
+/*void image_size(t_image* x,t_floatarg w,t_floatarg h) {
      x->x_width = w;
      x->x_height = h;
 	 image_displace((t_gobj*)x, x->x_glist, 0.0, 0.0);
-}
+}*/
 
-void image_color(t_image* x,t_symbol* col)
+/*void image_color(t_image* x,t_symbol* col)
 {
-/*     outlet_bang(x->x_obj.ob_outlet); only bang if there was a bang .. 
-       so color black does the same as bang, but doesn't forward the bang 
-*/
-}
+     //outlet_bang(x->x_obj.ob_outlet); only bang if there was a bang .. 
+     //so color black does the same as bang, but doesn't forward the bang 
+
+}*/
 
 /*static int image_newclick(t_gobj *z, struct _glist *glist, int xpix, int ypix, int shift, int alt, int dbl, int doit)
 {
@@ -260,17 +291,31 @@ void image_color(t_image* x,t_symbol* col)
 	return(1);
 }*/
 
+void image_gop_spill(t_image* x, t_floatarg f)
+{
+     x->x_gop_spill = (f >= 0 ? f : 0);
+	 image_displace((t_gobj*)x, x->x_glist, 0.0, 0.0);
+}
+
 void image_open(t_image* x, t_symbol *s, t_int argc, t_atom *argv)
 {
     x->x_fname = get_filename(argc, argv);
+	x->x_img_width = 0;
+	x->x_img_height = 0;
 	image_doopen(x);
 }
 
 static void image_imagesize_callback(t_image *x, t_float w, t_float h) {
-	//fprintf(stderr,"received w %f h %f\n",w,h);
+	//fprintf(stderr,"received w %f h %f should %d spill %d\n", w, h, gobj_shouldvis((t_gobj *)x, glist_getcanvas(x->x_glist)), x->x_gop_spill);
 	x->x_img_width = w;
 	x->x_img_height = h;
-	canvas_fixlinesfor(x->x_glist,(t_text*) x);
+	if (!gobj_shouldvis((t_gobj *)x, x->x_glist) && !x->x_gop_spill) {
+			//fprintf(stderr,"erasing\n");
+			image_erase(x, glist_getcanvas(x->x_glist));
+	} else {
+		sys_vgui("catch {.x%x.c delete %xMT}\n", x->x_glist, x);
+		canvas_fixlinesfor(x->x_glist,(t_text*) x);
+	}
 }
 
 static void image_setwidget(void)
@@ -303,8 +348,24 @@ static void *image_new(t_symbol *s, t_int argc, t_atom *argv)
 
     x->x_width = 15;
     x->x_height = 15;
+	x->x_img_width = 0;
+	x->x_img_height = 0;
+	x->x_gop_spill = 0;
+
+	x->x_fname = get_filename(argc, argv);
+	if (strlen(x->x_fname->s_name) > 0) {
+		//fprintf(stderr,"get_filename succeeded %s\n", x->x_fname->s_name);
+		argc--;
+		argv++;
+	}
 
-    x->x_fname = get_filename(argc, argv);
+	if (argc && argv[0].a_type == A_FLOAT) {
+		//we have optional gop_spill flag first
+		//fprintf(stderr,"gop_spill succeeded\n");
+		x->x_gop_spill = (int)atom_getfloat(&argv[0]);
+		argc--;
+		argv++;
+	}
 
 	// Create default receiver
 	char buf[MAXPDSTRING];
@@ -329,6 +390,8 @@ void image_setup(void)
 */
     class_addmethod(image_class, (t_method)image_open, gensym("open"),
     	A_GIMME, 0);
+    class_addmethod(image_class, (t_method)image_gop_spill, gensym("gopspill"),
+    	A_DEFFLOAT, 0);
     class_addmethod(image_class, (t_method)image_imagesize_callback,\
                      gensym("_imagesize"), A_DEFFLOAT, A_DEFFLOAT, 0);
 	
-- 
GitLab