From 71db6750ca27af3d839303c779f8e1a1271786c1 Mon Sep 17 00:00:00 2001
From: Ivica Ico Bukvic <ico@vt.edu>
Date: Tue, 22 Nov 2011 20:06:02 -0500
Subject: [PATCH] added gop move/resize via gui, improved logic on autoresizing
 objects to accomodate space for nlets (GOP-ed objects with hidden text can be
 of just abuot any size)

---
 src/g_all_guis.h |   2 +
 src/g_canvas.c   | 340 ++++++++++++++++++++++++++++++++++++++++++++++-
 src/g_canvas.h   |  12 ++
 src/g_editor.c   |  42 ++++--
 4 files changed, 384 insertions(+), 12 deletions(-)

diff --git a/src/g_all_guis.h b/src/g_all_guis.h
index c478950b0..81f32341a 100644
--- a/src/g_all_guis.h
+++ b/src/g_all_guis.h
@@ -120,6 +120,8 @@
 #define SCALE_VSLD_MINHEIGHT 2
 #define SCALE_VU_MINWIDTH 8
 #define SCALE_VU_MINHEIGHT 80
+#define SCALE_GOP_MINWIDTH 18
+#define SCALE_GOP_MINHEIGHT 12
 
 #define SCALEHANDLE_WIDTH   5
 #define SCALEHANDLE_HEIGHT  5
diff --git a/src/g_canvas.c b/src/g_canvas.c
index edc7e5f64..abaccd31a 100644
--- a/src/g_canvas.c
+++ b/src/g_canvas.c
@@ -12,8 +12,9 @@ to be different but are now unified except for some fossilized names.) */
 #include "s_stuff.h"
 #include "g_magicglass.h"
 #include "g_canvas.h"
-#include <string.h>
 #include "g_all_guis.h"
+#include <string.h>
+
 
     /* LATER consider adding font size to this struct (see glist_getfont()) */
 struct _canvasenvironment
@@ -347,7 +348,37 @@ void glist_init(t_glist *x)
     tells us which.) */
 t_canvas *canvas_new(void *dummy, t_symbol *sel, int argc, t_atom *argv)
 {
+	/*	first alloc one byte or redundant memory to prevent creation of objects with the same "name"
+		which leads to double-action invoked from every single action and eventually possible crashes
+
+		we keep a list of these redundant allocations and destroy them when pd quits */
+	//if (x->gl_owner && x->gl_env) {
+/*
+		t_redundant_mem *new_rm = (t_redundant_mem *)t_getbytes(sizeof(*new_rm));
+		new_rm->rm_what = (int)getbytes(1);
+		if (rm_start == NULL) {
+			//fprintf(stderr,"first allocation\n");
+			rm_start = new_rm;
+			rm_end = new_rm;
+		}
+		else if (rm_start == rm_end) {
+			//fprintf(stderr,"second allocation\n");
+			rm_end = new_rm;
+			rm_start->rm_next = rm_end;
+		}
+		else {
+			//fprintf(stderr,"allocation\n");
+			rm_end->rm_next = new_rm;
+			rm_end = new_rm;
+		}
+*/
+	//}
+
     t_canvas *x = (t_canvas *)pd_new(canvas_class);
+
+	/* now that we've created a new canvas, add canvas info to the new_rm */
+	//new_rm->rm_canvas = x;
+
     t_canvas *owner = canvas_getcurrent();
     t_symbol *s = &s_;
     int vis = 0, width = GLIST_DEFCANVASWIDTH, height = GLIST_DEFCANVASHEIGHT;
@@ -440,6 +471,38 @@ t_canvas *canvas_new(void *dummy, t_symbol *sel, int argc, t_atom *argv)
     x->gl_font = sys_nearestfontsize(font);
     pd_pushsym(&x->gl_pd);
 
+/* ---------- dpsaha@vt.edu gop resize -------------------------------- */
+	//resize blob	
+	t_scalehandle *sh;
+	char buf[64];
+	x->x_handle = pd_new(scalehandle_class);
+	sh = (t_scalehandle *)x->x_handle;
+	sh->h_master = (t_gobj*)x;
+	sprintf(buf, "_h%lx", (t_int)sh);
+	pd_bind(x->x_handle, sh->h_bindsym = gensym(buf));
+	sprintf(sh->h_outlinetag, "h%lx", (t_int)sh);
+	sh->h_dragon = 0;
+	sh->h_scale = 1;
+	x->scale_offset_x = 0;
+	x->scale_offset_y = 0;
+	x->scale_vis = 0;
+	
+	//move blob	
+	t_scalehandle *mh;
+	char mbuf[64];
+	x->x_mhandle = pd_new(scalehandle_class);
+	mh = (t_scalehandle *)x->x_mhandle;
+	mh->h_master = (t_gobj*)x;
+	sprintf(mbuf, "_h%lx", (t_int)mh);
+	pd_bind(x->x_mhandle, mh->h_bindsym = gensym(mbuf));
+	sprintf(mh->h_outlinetag, "h%lx", (t_int)mh);
+	mh->h_dragon = 0;
+	mh->h_scale = 0;
+	x->move_offset_x = 0;
+	x->move_offset_y = 0;
+	x->move_vis = 0;
+/*------------------------------------------------------------- */
+
     return(x);
 }
 
@@ -657,9 +720,60 @@ void canvas_dirty(t_canvas *x, t_floatarg n)
     }
 }
 
+/*********** dpsaha@vt.edu resize move hooks ****************/
+void canvas_draw_gop_resize_hooks(t_canvas* x)
+{
+	if(x->gl_edit){
+		
+		//Drawing and Binding Resize_Blob for GOP
+		t_scalehandle *sh = (t_scalehandle *)(x->x_handle);
+		sprintf(sh->h_pathname, ".x%lx.h%lx", (t_int)x, (t_int)sh);
+		sys_vgui("destroy %s\n", sh->h_pathname);		
+		sys_vgui("canvas %s -width %d -height %d -bg $select_color -bd 0 -cursor bottom_right_corner\n",
+				 sh->h_pathname, SCALEHANDLE_WIDTH, SCALEHANDLE_HEIGHT);
+		sys_vgui(".x%x.c create window %d %d -anchor nw -width %d -height %d -window %s -tags {%lxSCALE %lxGOP GOP_resblob}\n",
+				 x, x->gl_xmargin + x->gl_pixwidth - SCALEHANDLE_WIDTH - 1,
+				 x->gl_ymargin + 3 + x->gl_pixheight - SCALEHANDLE_HEIGHT - 4,
+				 SCALEHANDLE_WIDTH, SCALEHANDLE_HEIGHT,
+				 sh->h_pathname, x, x);
+		
+		sys_vgui("bind %s <Button> {pd [concat %s _click 1 %%x %%y \\;]}\n",
+				 sh->h_pathname, sh->h_bindsym->s_name);
+		sys_vgui("bind %s <ButtonRelease> {pd [concat %s _click 0 0 0 \\;]}\n",
+				 sh->h_pathname, sh->h_bindsym->s_name);
+		sys_vgui("bind %s <Motion> {pd [concat %s _motion %%x %%y \\;]}\n",
+				 sh->h_pathname, sh->h_bindsym->s_name);
+
+		//Drawing and Binding Move_Blob for GOP
+		t_scalehandle *mh = (t_scalehandle *)(x->x_mhandle);
+		sprintf(mh->h_pathname, ".x%lx.h%lx", (t_int)x, (t_int)mh);
+		sys_vgui("destroy %s\n", mh->h_pathname);		
+		sys_vgui("canvas %s -width %d -height %d -bg $select_color -bd 0 -cursor crosshair\n",
+				 mh->h_pathname, SCALEHANDLE_WIDTH, SCALEHANDLE_HEIGHT);
+		sys_vgui(".x%x.c create window %d %d -anchor nw -width %d -height %d -window %s -tags {%lxMOVE %lxGOP GOP_movblob}\n",
+				 x, x->gl_xmargin + 2 ,
+				 x->gl_ymargin + 2 ,
+				 SCALEHANDLE_WIDTH, SCALEHANDLE_HEIGHT,
+				 mh->h_pathname, x, x);
+		
+		sys_vgui("bind %s <Button> {pd [concat %s _click 1 %%x %%y \\;]}\n",
+				 mh->h_pathname, mh->h_bindsym->s_name);
+		sys_vgui("bind %s <ButtonRelease> {pd [concat %s _click 0 0 0 \\;]}\n",
+				 mh->h_pathname, mh->h_bindsym->s_name);
+		sys_vgui("bind %s <Motion> {pd [concat %s _motion %%x %%y \\;]}\n",
+				 mh->h_pathname, mh->h_bindsym->s_name);
+
+	}
+	else{
+		sys_vgui(".x%lx.c delete GOP_resblob\n",x);					//delete the GOP_resblob
+		sys_vgui(".x%lx.c delete GOP_movblob\n",x);					//delete the GOP_movblob	
+	}
+}
+/*****************************************************************************/
+
 void canvas_drawredrect(t_canvas *x, int doit)
 {
-    if (doit)
+    if (doit){
         sys_vgui(".x%lx.c create line\
             %d %d %d %d %d %d %d %d %d %d -fill #ff8080 -tags GOP\n",
             glist_getcanvas(x),
@@ -668,6 +782,10 @@ void canvas_drawredrect(t_canvas *x, int doit)
             x->gl_xmargin + x->gl_pixwidth, x->gl_ymargin + x->gl_pixheight,
             x->gl_xmargin, x->gl_ymargin + x->gl_pixheight,
             x->gl_xmargin, x->gl_ymargin);
+		if (x->gl_goprect && x->gl_edit){
+				canvas_draw_gop_resize_hooks(x);					//dpsaha@vt.edu for drawing the GOP_blobs
+		}	
+	}
     else sys_vgui(".x%lx.c delete GOP\n",  glist_getcanvas(x));
 }
 
@@ -1623,6 +1741,215 @@ int canvas_open(t_canvas *x, const char *name, const char *ext,
         dirresult, nameresult, size, bin));
 }
 
+void canvasgop_draw_move(t_canvas *x, int doit)
+{
+	//delete the earlier GOP window so that when dragging 
+	//there is only one GOP window present on parent
+	sys_vgui(".x%lx.c delete GOP\n",  x);
+		
+	//redraw the GOP
+	canvas_setgraph(x, x->gl_isgraph+2*x->gl_hidetext, 0);
+	canvas_dirty(x, 1);
+	if (x->gl_havewindow) {
+	    canvas_redraw(x);
+	}
+	if (x->gl_owner && glist_isvisible(x->gl_owner))
+	{
+		glist_noselect(x);
+	    gobj_vis(&x->gl_gobj, x->gl_owner, 0);
+	    gobj_vis(&x->gl_gobj, x->gl_owner, 1);
+		canvas_redraw(x->gl_owner);
+	}
+	
+	//update scrollbars when GOP potentially exceeds window size
+	t_canvas *canvas=(t_canvas *)glist_getcanvas(x);
+	
+	//if gop is being disabled go one level up
+	if (!x->gl_isgraph && x->gl_owner) {
+		canvas=canvas->gl_owner;
+		canvas_redraw(canvas);
+	}
+	sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", (t_int)x);
+	sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", (t_int)canvas);
+}
+
+extern int gfxstub_haveproperties(void *key);
+extern void canvas_canvas_setundo(t_canvas *x);
+
+void canvasgop__clickhook(t_scalehandle *sh, t_floatarg f, t_floatarg xxx, t_floatarg yyy)
+{
+	int x1=0, y1=0, x2=0, y2=0; //for getrect
+
+	t_canvas *x = (t_canvas *)(sh->h_master);
+
+ 	if (xxx) x->scale_offset_x = xxx;
+ 	if (yyy) x->scale_offset_y = yyy;
+
+    int newstate = (int)f;
+    if (sh->h_dragon && newstate == 0)
+    {
+		/* done dragging */
+		if(sh->h_scale)														//enter if resize_gop hook
+		{
+			/* first set up the undo apply */
+			canvas_canvas_setundo(x);
+
+			if (sh->h_dragx || sh->h_dragy) 
+			{
+				x->gl_pixwidth = x->gl_pixwidth + sh->h_dragx - x->scale_offset_x;
+				if (x->gl_pixwidth < SCALE_GOP_MINWIDTH)
+					x->gl_pixwidth = SCALE_GOP_MINWIDTH;
+				x->gl_pixheight = x->gl_pixheight + sh->h_dragy - x->scale_offset_y;
+				if (x->gl_pixheight < SCALE_GOP_MINHEIGHT)
+					x->gl_pixheight = SCALE_GOP_MINHEIGHT;
+
+				// TODO check if the text is not hidden
+				// if so make minimum width and height based retrieved from getrect
+				if (x->gl_hidetext == 0 && x->gl_owner) {
+					gobj_getrect((t_gobj*)x, x->gl_owner, &x1, &y1, &x2, &y2);
+					if (x2-x1 > x->gl_pixwidth) x->gl_pixwidth = x2-x1;
+					if (y2-y1 > x->gl_pixheight) x->gl_pixheight = y2-y1;
+				}
+
+				canvas_dirty(x, 1);
+			}
+
+			int properties = gfxstub_haveproperties((void *)x);
+
+			if (properties) {
+				sys_vgui(".gfxstub%lx.xrange.entry3 delete 0 end\n", properties);
+				sys_vgui(".gfxstub%lx.xrange.entry3 insert 0 %d\n", properties, x->gl_pixwidth);
+				sys_vgui(".gfxstub%lx.yrange.entry3 delete 0 end\n", properties);
+				sys_vgui(".gfxstub%lx.yrange.entry3 insert 0 %d\n", properties, x->gl_pixheight);
+			}
+
+			if (glist_isvisible(x))
+			{
+				sys_vgui(".x%x.c delete %s\n", x, sh->h_outlinetag);
+				canvasgop_draw_move(x,1);
+				canvas_fixlinesfor(x, (t_text *)x);
+				sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", x);
+			}
+		}
+		else 																//enter if move_gop hook
+		{
+			/* first set up the undo apply */
+			canvas_canvas_setundo(x);
+
+			if (sh->h_dragx || sh->h_dragy) 
+			{
+				x->gl_xmargin = x->gl_xmargin + sh->h_dragx - x->scale_offset_x;
+				x->gl_ymargin = x->gl_ymargin + sh->h_dragy - x->scale_offset_y;
+				
+				canvas_dirty(x, 1);
+			}
+
+			int properties = gfxstub_haveproperties((void *)x);
+			if (properties) {
+				sys_vgui(".gfxstub%lx.xrange.entry4 delete 0 end\n", properties);
+				sys_vgui(".gfxstub%lx.xrange.entry4 insert 0 %d\n", properties, x->gl_xmargin);
+				sys_vgui(".gfxstub%lx.yrange.entry4 delete 0 end\n", properties);
+				sys_vgui(".gfxstub%lx.yrange.entry4 insert 0 %d\n", properties, x->gl_ymargin);
+			}
+		
+			if (glist_isvisible(x))
+			{
+				canvasgop_draw_move(x,1);
+				canvas_fixlinesfor(x, (t_text *)x);
+				sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", x);
+			}
+		}
+    }
+	else if (!sh->h_dragon && newstate)
+    {
+		if(sh->h_scale)														//enter if resize_gop hook
+		{
+			
+			sys_vgui("lower %s\n", sh->h_pathname);
+			sys_vgui(".x%lx.c delete GOP \n",  x);							//delete GOP rect where it started from
+			sys_vgui(".x%x.c create rectangle %d %d %d %d\
+	 			-outline $select_color -width 1 -tags %s\n",\
+				 x, x->gl_xmargin, x->gl_ymargin,\
+					x->gl_xmargin + x->gl_pixwidth,\
+					x->gl_ymargin + x->gl_pixheight, sh->h_outlinetag);
+
+			sh->h_dragx = 0;
+			sh->h_dragy = 0;
+		}
+		else																//enter if move_gop hook
+		{
+			sys_vgui("lower %s\n", sh->h_pathname);
+			sys_vgui(".x%lx.c delete GOP_resblob \n",  x);					//delete GOP_resblob when moving the whole GOP
+
+			sh->h_dragx = 0;
+			sh->h_dragy = 0;
+		}
+    }
+
+	sh->h_dragon = newstate;
+}
+
+void canvasgop__motionhook(t_scalehandle *sh,t_floatarg f1, t_floatarg f2)
+{
+	t_canvas *x = (t_canvas *)(sh->h_master);
+	int dx = (int)f1, dy = (int)f2;
+	int newx, newy;
+	
+	if (sh->h_dragon)
+    {
+		if(sh->h_scale)													//enter if resize_gop hook
+		{			
+			newx = x->gl_xmargin + x->gl_pixwidth - x->scale_offset_x + dx;
+			newy = x->gl_ymargin + x->gl_pixheight - x->scale_offset_y + dy;
+
+			if (newx < x->gl_xmargin + SCALE_GOP_MINWIDTH)
+				newx = x->gl_xmargin + SCALE_GOP_MINWIDTH;
+			if (newy < x->gl_ymargin + SCALE_GOP_MINHEIGHT)
+				newy = x->gl_ymargin + SCALE_GOP_MINHEIGHT;
+
+			sys_vgui(".x%x.c coords %s %d %d %d %d\n",
+				 x, sh->h_outlinetag, x->gl_xmargin,
+				 x->gl_ymargin, newx, newy);
+
+			sh->h_dragx = dx;
+			sh->h_dragy = dy;
+
+			int properties = gfxstub_haveproperties((void *)x);
+			if (properties) {
+				int new_w = x->gl_pixwidth - x->scale_offset_x + sh->h_dragx;
+				int new_h = x->gl_pixheight - x->scale_offset_y + sh->h_dragy;
+				sys_vgui(".gfxstub%lx.xrange.entry3 delete 0 end\n", properties);
+				sys_vgui(".gfxstub%lx.xrange.entry3 insert 0 %d\n", properties, new_w);
+				sys_vgui(".gfxstub%lx.yrange.entry3 delete 0 end\n", properties);
+				sys_vgui(".gfxstub%lx.yrange.entry3 insert 0 %d\n", properties, new_h);
+			}
+		}
+		else															//enter if move_gop hook
+		{
+			newx = x->gl_xmargin - x->scale_offset_x + dx;
+			newy = x->gl_ymargin - x->scale_offset_y + dy;
+		
+			int properties = gfxstub_haveproperties((void *)x);
+			if (properties) {
+				sys_vgui(".gfxstub%lx.xrange.entry4 delete 0 end\n", properties);
+				sys_vgui(".gfxstub%lx.xrange.entry4 insert 0 %d\n", properties, newx);
+				sys_vgui(".gfxstub%lx.yrange.entry4 delete 0 end\n", properties);
+				sys_vgui(".gfxstub%lx.yrange.entry4 insert 0 %d\n", properties, newy);
+			}
+
+			sys_vgui(".x%x.c coords GOP %d %d %d %d %d %d %d %d %d %d\n",
+						x, newx, newy, newx+x->gl_pixwidth, newy,
+						newx+x->gl_pixwidth, newy+x->gl_pixheight,
+						newx, newy+x->gl_pixheight,
+						newx, newy);
+
+			sh->h_dragx = dx;
+			sh->h_dragy = dy;			
+		}
+    }
+}
+/*------------------------------------------------------------------------*/
+
 /* ------------------------------- setup routine ------------------------ */
 
     /* why are some of these "glist" and others "canvas"? */
@@ -1754,4 +2081,13 @@ void g_canvas_setup(void)
     g_graph_setup();
     g_editor_setup();
     g_readwrite_setup();
+
+/* -------------- dpsaha@vt.edu gop resize move-----------------------*/
+	scalehandle_class = class_new(gensym("_scalehandle"), 0, 0,
+				  sizeof(t_scalehandle), CLASS_PD, 0);
+	class_addmethod(scalehandle_class, (t_method)canvasgop__clickhook,
+		    gensym("_click"), A_FLOAT, A_FLOAT, A_FLOAT, 0);
+    class_addmethod(scalehandle_class, (t_method)canvasgop__motionhook,
+		    gensym("_motion"), A_FLOAT, A_FLOAT, 0);
+
 }
diff --git a/src/g_canvas.h b/src/g_canvas.h
index d73c6ac8f..6344bfdbd 100644
--- a/src/g_canvas.h
+++ b/src/g_canvas.h
@@ -214,6 +214,18 @@ struct _glist
     t_magicGlass *gl_magic_glass;   /* magic glass object */
     // end jsarlo
 	//t_clock  *gl_destroy;			/* for script-based closing of the patch */
+
+	//dpsaha@vt.edu for the gop dynamic resizing
+	t_pd	   		   *x_handle;
+	int 			   scale_offset_x;	
+	int				   scale_offset_y;
+	int				   scale_vis;
+	
+	//dpsaha@vt.edu for the move handle
+	t_pd			   *x_mhandle;
+	int				   move_offset_x;
+	int				   move_offset_y;
+	int				   move_vis;
 };
 
 #define gl_gobj gl_obj.te_g
diff --git a/src/g_editor.c b/src/g_editor.c
index 58f9e178b..b80b6bd32 100644
--- a/src/g_editor.c
+++ b/src/g_editor.c
@@ -1209,11 +1209,11 @@ static void canvas_undo_canvas_apply(t_canvas *x, void *z, int action)
 
 	if (action == UNDO_UNDO || action == UNDO_REDO)
 	{
-		//close properties window first
+		/*//close properties window first
 		t_int properties = gfxstub_haveproperties((void *)x);
 		if (properties) {
 			sys_vgui("destroy .gfxstub%lx\n", properties);
-		}
+		}*/
 
 		//store current canvas values into temporary data holder
 		tmp.gl_pixwidth = x->gl_pixwidth;
@@ -1281,11 +1281,26 @@ static void canvas_undo_canvas_apply(t_canvas *x, void *z, int action)
 		}
 		//update scrollbars when GOP potentially exceeds window size
 		t_canvas *canvas=(t_canvas *)glist_getcanvas(x);
+
 		//if gop is being disabled go one level up
 		if (!x->gl_isgraph && x->gl_owner) {
 			canvas=canvas->gl_owner;
 			canvas_redraw(canvas);
 		}
+
+		//if properties window is open, update the properties with the previous window properties		
+		t_int properties = gfxstub_haveproperties((void *)x);
+		if (properties) {
+			sys_vgui(".gfxstub%lx.xrange.entry3 delete 0 end\n", properties);
+			sys_vgui(".gfxstub%lx.xrange.entry3 insert 0 %d\n", properties, x->gl_pixwidth);
+			sys_vgui(".gfxstub%lx.yrange.entry3 delete 0 end\n", properties);
+			sys_vgui(".gfxstub%lx.yrange.entry3 insert 0 %d\n", properties, x->gl_pixheight);
+			sys_vgui(".gfxstub%lx.xrange.entry4 delete 0 end\n", properties);
+			sys_vgui(".gfxstub%lx.xrange.entry4 insert 0 %d\n", properties, x->gl_xmargin);
+			sys_vgui(".gfxstub%lx.yrange.entry4 delete 0 end\n", properties);
+			sys_vgui(".gfxstub%lx.yrange.entry4 insert 0 %d\n", properties, x->gl_ymargin);
+		}
+
 		sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", (t_int)x);
 		sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", (t_int)canvas);
 	}
@@ -3028,13 +3043,13 @@ void glob_verifyquit(void *dummy, t_floatarg f)
     else glob_quit(0);
 }
 
-void canvas_dofree(t_gobj *dummy, t_glist *x)
-{
+//void canvas_dofree(t_gobj *dummy, t_glist *x)
+//{
 	//int dspstate = canvas_suspend_dsp();
 	//sys_flushqueue();
-	pd_free(&x->gl_pd);
+	//pd_free(&x->gl_pd);
 	//canvas_resume_dsp(dspstate);
-}
+//}
 
     /* close a window (or possibly quit Pd), checking for dirty flags.
     The "force" parameter is interpreted as follows:
@@ -3087,10 +3102,10 @@ void canvas_menuclose(t_canvas *x, t_floatarg fforce)
     else if (force == 1) {
 		//sys_vgui("pd {.x%lx menuclose -1;}\n", x);
 		//sys_vgui("menu_close .x%lx\n", x);
-		sys_queuegui(x, x, canvas_dofree);
+		//sys_queuegui(x, x, canvas_dofree);
 		//canvas_vis(x, 0);
 		//canvas_free(x);
-		//pd_free(&x->gl_pd);
+		pd_free(&x->gl_pd);
 		//fprintf(stderr,"pd_free queued------------\n");
 		//clock_delay(x->gl_destroy, 0);
 	}
@@ -4035,6 +4050,8 @@ void glob_key(void *dummy, t_symbol *s, int ac, t_atom *av)
     canvas_key(canvas_editing, s, ac, av);
 }
 
+extern void canvas_draw_gop_resize_hooks(t_canvas *x);
+
 void canvas_editmode(t_canvas *x, t_floatarg fyesplease)
 {
 	//fprintf(stderr,"canvas_editmode %f\n", fyesplease);
@@ -4045,10 +4062,13 @@ void canvas_editmode(t_canvas *x, t_floatarg fyesplease)
         return;
 	}
     x->gl_edit = !x->gl_edit;
-    if (x->gl_edit && glist_isvisible(x) && glist_istoplevel(x))
-	 canvas_setcursor(x, CURSOR_EDITMODE_NOTHING);
+    if (x->gl_edit && glist_isvisible(x) && glist_istoplevel(x)){
+		if (x->gl_goprect)	canvas_draw_gop_resize_hooks(x);								// dpsaha@vt.edu add the resize blobs on GOP
+		canvas_setcursor(x, CURSOR_EDITMODE_NOTHING);
+	}
     else
     {
+		//fprintf(stderr,"we are out of edit\n");
         glist_noselect(x);
         if (glist_isvisible(x) && glist_istoplevel(x))
         {
@@ -4085,6 +4105,8 @@ void canvas_editmode(t_canvas *x, t_floatarg fyesplease)
 	else {
 		sys_vgui(".x%lx.m.edit entryconfigure \"Cord Inspector\" -indicatoron false -state normal\n", glist_getcanvas(x));
 	}*/
+	//dpsaha@vt.edu called to delete the GOP_blob
+	if (x->gl_goprect)		canvas_draw_gop_resize_hooks(x);
 }
 
 // jsarlo
-- 
GitLab