diff --git a/pd/src/g_all_guis.c b/pd/src/g_all_guis.c
index 9bfdf505bf64952353fbbf020fec220eb05f5874..51e54911435ed85bc9402bf3fa892b48a59a78f4 100644
--- a/pd/src/g_all_guis.c
+++ b/pd/src/g_all_guis.c
@@ -26,6 +26,8 @@
 #include <io.h>
 #endif
 
+t_symbol *s_empty;
+
 /*  #define GGEE_HSLIDER_COMPATIBLE  */
 
 /*------------------ global varaibles -------------------------*/
@@ -861,7 +863,6 @@ void iem_inttofstyle(t_iem_fstyle_flags *fstylep, int n)
 {
     memset(fstylep, 0, sizeof(*fstylep));
     fstylep->x_font_style = (n >> 0);
-    fstylep->x_shiftdown = 0;
     fstylep->x_selected = 0;
     fstylep->x_finemoved = 0;
     fstylep->x_put_in2out = 0;
@@ -894,7 +895,7 @@ char *iem_get_tag(t_canvas *glist, t_iemgui *iem_obj)
 }
 
 //----------------------------------------------------------------
-// SCALEHANDLE COMMON CODE
+// SCALEHANDLE COMMON CODE (by Mathieu, refactored from existing code)
 
 extern int gfxstub_haveproperties(void *key);
 
@@ -1102,3 +1103,110 @@ void scalehandle_drag_scale(t_scalehandle *h) {
     }
 }
 
+//----------------------------------------------------------------
+// IEMGUI refactor (by Mathieu)
+
+void iemgui_tag_selected(t_iemgui *x, t_glist *canvas, const char *class_tag) {
+    if(x->x_fsf.x_selected)
+        sys_vgui(".x%lx.c addtag selected withtag %lx%s\n", canvas, x, class_tag);
+    else
+        sys_vgui(".x%lx.c dtag %lx%s selected\n", canvas, x, class_tag);
+}
+
+void iemgui_label_draw_new(t_iemgui *x, t_glist *canvas, int xpos, int ypos, const char *nlet_tag, const char *class_tag) {
+    sys_vgui(".x%lx.c create text %d %d -text {%s} -anchor w "
+             "-font {{%s} -%d %s} -fill #%6.6x "
+             "-tags {%lxLABEL %lx%s text iemgui %s}\n",
+         canvas, xpos+x->x_ldx, ypos+x->x_ldy,
+         strcmp(x->x_lab->s_name, "empty")?x->x_lab->s_name:"",
+         x->x_font, x->x_fontsize, sys_fontweight,
+         x->x_lcol, x, x, class_tag, nlet_tag);
+}
+void iemgui_label_draw_move(t_iemgui *x, t_glist *canvas, int xpos, int ypos) {
+    sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",
+        canvas, x, xpos+x->x_ldx, ypos+x->x_ldy);
+}
+void iemgui_label_draw_config(t_iemgui *x, t_glist *canvas) {
+    if (x->x_fsf.x_selected && x->x_glist == canvas)
+        sys_vgui(".x%lx.c itemconfigure %lxLABEL -font {{%s} -%d %s} "
+                 "-fill $pd_colors(selection) -text {%s} \n",
+             canvas, x, x->x_font, x->x_fontsize, sys_fontweight,
+             strcmp(x->x_lab->s_name, "empty")?x->x_lab->s_name:"");
+    else
+        sys_vgui(".x%lx.c itemconfigure %lxLABEL -font {{%s} -%d %s} "
+                 "-fill #%6.6x -text {%s} \n",
+             canvas, x, x->x_font, x->x_fontsize, sys_fontweight,
+             x->x_lcol, strcmp(x->x_lab->s_name, "empty")?x->x_lab->s_name:"");
+}
+void iemgui_label_draw_select(t_iemgui *x, t_glist *canvas) {
+    if(x->x_fsf.x_selected)
+        sys_vgui(".x%lx.c itemconfigure %lxLABEL "
+            "-fill $pd_colors(selection)\n", canvas, x);
+    else
+        sys_vgui(".x%lx.c itemconfigure %lxLABEL -fill #%6.6x\n",
+            canvas, x, x->x_lcol);
+}
+
+void iemgui_io_draw(t_iemgui *x, t_glist *canvas, int old_sr_flags, const char *class_tag) {
+    int a,b;
+    t_class *c = pd_class((t_pd *)x);
+    //printf("--- iemgui_io_draw %s flags=%d\n",c->c_name->s_name,old_sr_flags);
+    char *nlet_tag = iem_get_tag(/*glist*/ x->x_glist, (t_iemgui *)x);
+
+    if (!(old_sr_flags&4) && (!glist_isvisible(canvas) || !(canvas == x->x_glist))) {
+        //printf("---/iemgui_io_draw not visible\n");
+        return;
+    }
+
+    int x1,y1,x2,y2;
+    c->c_wb->w_getrectfn((t_gobj *)x,canvas,&x1,&y1,&x2,&y2);
+
+    a=old_sr_flags&IEM_GUI_OLD_SND_FLAG;
+    //b=x->x_fsf.x_snd_able; // not inited at moment of new
+    b=x->x_snd!=s_empty;
+    //printf("a=%d b=%d snd=%s\n",a,b,x->x_snd->s_name);
+    if(a && !b)
+        //printf("%s create outlet\n",c->c_name->s_name), fflush(stdout),
+        sys_vgui(".x%lx.c create prect %d %d %d %d "
+                 "-stroke $pd_colors(iemgui_nlet) "
+                 "-tags {%lx%s%so%d %so%d %lx%s outlet iemgui %s}\n",
+             canvas, x1, y2-1, x1 + IOWIDTH, y2,
+             x, class_tag, nlet_tag, 0, nlet_tag, 0, x, class_tag, nlet_tag);
+    if(!a && b)
+        //printf("%s delete outlet\n",c->c_name->s_name), fflush(stdout),
+        sys_vgui(".x%lx.c delete %lx%s%so%d\n", canvas, x, class_tag, nlet_tag, 0);
+
+    a=old_sr_flags&IEM_GUI_OLD_RCV_FLAG;
+    //b=x->x_fsf.x_rcv_able; // not inited at moment of new
+    b=x->x_rcv!=s_empty;
+    //printf("a=%d b=%d rcv=%s\n",a,b,x->x_rcv->s_name);
+    if(a && !b)
+        //printf("%s create inlet\n",c->c_name->s_name), fflush(stdout),
+        sys_vgui(".x%lx.c create prect %d %d %d %d "
+                 "-stroke $pd_colors(iemgui_nlet) "
+                 "-tags {%lx%s%si%d %si%d %lx%s inlet iemgui %s}\n",
+             canvas, x1, y1, x1 + IOWIDTH, y1+1,
+             x, class_tag, nlet_tag, 0, nlet_tag, 0, x, class_tag, nlet_tag);
+    if(!a && b)
+        //printf("%s delete inlet\n",c->c_name->s_name), fflush(stdout),
+        sys_vgui(".x%lx.c delete %lx%s%si%d\n", canvas, x, class_tag, nlet_tag, 0);
+    //printf("---/iemgui_io_draw\n");
+}
+
+void iemgui_draw_erase(t_iemgui *x, t_glist* glist, const char *class_tag) {
+    t_canvas *canvas=glist_getcanvas(glist);
+    sys_vgui(".x%lx.c delete %lx%s\n", canvas, x, class_tag);
+    sys_vgui(".x%lx.c dtag all %lx%s\n", canvas, x, class_tag);
+    scalehandle_draw_erase2(x,glist);
+}
+
+void wb_init(t_widgetbehavior *wb, t_getrectfn gr, t_clickfn cl) {
+    wb->w_getrectfn = gr;
+    wb->w_displacefn = iemgui_displace;
+    wb->w_selectfn = iemgui_select;
+    wb->w_activatefn = NULL;
+    wb->w_deletefn = iemgui_delete;
+    wb->w_visfn = iemgui_vis;
+    wb->w_clickfn = cl;
+    wb->w_displacefnwtag = iemgui_displace_withtag;
+}
diff --git a/pd/src/g_all_guis.h b/pd/src/g_all_guis.h
index e28f90d0df196689497f99ad299535dec5c7b8a7..ebaffb91ee54e562edb56b8f38c0864773259248 100644
--- a/pd/src/g_all_guis.h
+++ b/pd/src/g_all_guis.h
@@ -84,7 +84,7 @@
 #define IEM_GUI_DRAW_MODE_SELECT 3
 #define IEM_GUI_DRAW_MODE_ERASE  4
 #define IEM_GUI_DRAW_MODE_CONFIG 5
-#define IEM_GUI_DRAW_MODE_IO     6
+#define IEM_GUI_DRAW_MODE_IO     6 /* also reserves 7,8,9 by adding old_sr_flags */
 
 
 #define IS_A_POINTER(atom,index) ((atom+index)->a_type == A_POINTER)
@@ -102,65 +102,39 @@
 #define IEM_GUI_COLOR_EDITED 16711680
 #define IEMGUI_MAX_NUM_LEN 32
 
-#define SCALE_BNG_MINWIDTH 8
-#define SCALE_BNG_MINHEIGHT 8
-#define SCALE_CNV_MINWIDTH 1
-#define SCALE_CNV_MINHEIGHT 1
-#define SCALE_HRDO_MINWIDTH 8
-#define SCALE_HRDO_MINHEIGHT 8
-#define SCALE_HSLD_MINWIDTH 2
-#define SCALE_HSLD_MINHEIGHT 8
 #define SCALE_NUM_MINWIDTH 1
 #define SCALE_NUM_MINHEIGHT 8
-#define SCALE_TGL_MINWIDTH 8
-#define SCALE_TGL_MINHEIGHT 8
-#define SCALE_VRDO_MINWIDTH 8
-#define SCALE_VRDO_MINHEIGHT 8
-#define SCALE_VSLD_MINWIDTH 8
-#define SCALE_VSLD_MINHEIGHT 2
-#define SCALE_VU_MINWIDTH 8
-#define SCALE_VU_MINHEIGHT 80
 #define SCALE_GOP_MINWIDTH 12
 #define SCALE_GOP_MINHEIGHT 12
-
 #define SCALEHANDLE_WIDTH   5
 #define SCALEHANDLE_HEIGHT  5
-
 #define LABELHANDLE_WIDTH   5
 #define LABELHANDLE_HEIGHT  5
 
-typedef struct _iem_fstyle_flags
-{
-    unsigned int x_font_style:6;
-    unsigned int x_rcv_able:1;
-    unsigned int x_snd_able:1;
-    unsigned int x_lab_is_unique:1;
-    unsigned int x_rcv_is_unique:1;
-    unsigned int x_snd_is_unique:1;
-    unsigned int x_lab_arg_tail_len:6;
-    unsigned int x_lab_is_arg_num:6;
-    unsigned int x_shiftdown:1;
-    unsigned int x_selected:1;
-    unsigned int x_finemoved:1;
-    unsigned int x_put_in2out:1;
-    unsigned int x_change:1;
-    unsigned int x_thick:1;
-    unsigned int x_lin0_log1:1;
-    unsigned int x_steady:1;
+typedef struct _iem_fstyle_flags // (15 used of 32)
+{                                 // grep -w "$1" *.[ch]|wc -l (after refactor#5)
+    unsigned int x_font_style:6;  // 56 matches
+    unsigned int x_rcv_able:1;    // 59 matches
+    unsigned int x_snd_able:1;    // 65 matches
+    unsigned int unused:16;
+    unsigned int x_selected:1;    // 38 matches
+    unsigned int x_finemoved:1;   // 11 matches
+    unsigned int x_put_in2out:1;  // 17 matches
+    unsigned int x_change:1;      // 37 matches
+    unsigned int x_thick:1;       // 14 matches
+    unsigned int x_lin0_log1:1;   // 38 matches
+    unsigned int x_steady:1;      // 18 matches
     unsigned int dummy:1;
 } t_iem_fstyle_flags;
 
-typedef struct _iem_init_symargs
+typedef struct _iem_init_symargs // (5 used of 32)
 {
-    unsigned int x_loadinit:1;
-    unsigned int x_rcv_arg_tail_len:6;
-    unsigned int x_snd_arg_tail_len:6;
-    unsigned int x_rcv_is_arg_num:6;
-    unsigned int x_snd_is_arg_num:6;
-    unsigned int x_scale:1;
-    unsigned int x_flashed:1;
-    unsigned int x_locked:1;
-    unsigned int x_reverse:1; /* bugfix */
+    unsigned int x_loadinit:1;         // 33 matches
+    unsigned int unused:24;
+    unsigned int x_scale:1;            // 22 matches
+    unsigned int x_flashed:1;          // 16 matches
+    unsigned int x_locked:1;           //  8 matches
+    unsigned int x_reverse:1; /* bugfix */ // 8 matches
     unsigned int dummy:3;
 } t_iem_init_symargs;
 
@@ -422,3 +396,15 @@ EXTERN void scalehandle_drag_scale(t_scalehandle *h);
 EXTERN int mini(int a, int b);
 EXTERN int maxi(int a, int b);
 
+// other refactor by Mathieu
+EXTERN void iemgui_tag_selected(     t_iemgui *x, t_glist *canvas, const char *class_tag);
+EXTERN void iemgui_label_draw_new(   t_iemgui *x, t_glist *canvas, int xpos, int ypos, const char *nlet_tag, const char *class_tag);
+EXTERN void iemgui_label_draw_move(  t_iemgui *x, t_glist *canvas, int xpos, int ypos);
+EXTERN void iemgui_label_draw_config(t_iemgui *x, t_glist *canvas);
+EXTERN void iemgui_label_draw_select(t_iemgui *x, t_glist *canvas);
+EXTERN void iemgui_io_draw(t_iemgui *x, t_glist *canvas, int old_sr_flags, const char *class_tag);
+EXTERN void iemgui_draw_erase(t_iemgui *x, t_glist* glist, const char *class_tag);
+
+EXTERN void wb_init(t_widgetbehavior *wb, t_getrectfn gr, t_clickfn cl);
+
+extern t_symbol *s_empty;
diff --git a/pd/src/g_bang.c b/pd/src/g_bang.c
index ffa17069f718fd0697f306b0866dfd9b8b77bd9c..559075ec8d92232a67a1aab571b7e3804564ec34 100644
--- a/pd/src/g_bang.c
+++ b/pd/src/g_bang.c
@@ -45,11 +45,15 @@ void bng_draw_update(t_gobj *xgobj, t_glist *glist)
             sys_vgui(".x%lx.c itemconfigure %lxBUT -fill #%6.6x\n",
                 glist_getcanvas(glist), x,
                 x->x_flashed?x->x_gui.x_fcol:x->x_gui.x_bcol);
-            //vcanvas_itemconf(glist,x,"BUT","-fill",x->x_flashed?x->x_gui.x_fcol:x->x_gui.x_bcol);
         }
         x->x_gui.x_changed = x->x_flashed;
     }
 }
+void bng_draw_io(t_bng* x, t_glist* glist, int old_snd_rcv_flags)
+{
+    t_canvas *canvas=glist_getcanvas(glist);
+    iemgui_io_draw(&x->x_gui,canvas,old_snd_rcv_flags,"BNG");
+}
 
 void bng_draw_new(t_bng *x, t_glist *glist)
 {
@@ -60,8 +64,6 @@ void bng_draw_new(t_bng *x, t_glist *glist)
     scalehandle_draw_new(x->x_gui. x_handle,canvas);
     scalehandle_draw_new(x->x_gui.x_lhandle,canvas);
 
-    //if (glist_isvisible(canvas)) {
-
     char *nlet_tag = iem_get_tag(glist, (t_iemgui *)x);
 
     sys_vgui(".x%lx.c create prect %d %d %d %d "
@@ -77,32 +79,8 @@ void bng_draw_new(t_bng *x, t_glist *glist)
              "-tags {%lxBUT %lxBNG text iemgui border %s}\n",
          canvas, cx, cy, cr, x->x_flashed?x->x_gui.x_fcol:x->x_gui.x_bcol,
          x, x, nlet_tag);
-    sys_vgui(".x%lx.c create text %d %d -text {%s} -anchor w "
-             "-font {{%s} -%d %s} -fill #%6.6x "
-             "-tags {%lxLABEL %lxBNG text iemgui %s}\n",
-         canvas, xpos+x->x_gui.x_ldx,
-         ypos+x->x_gui.x_ldy,
-         strcmp(x->x_gui.x_lab->s_name, "empty")?x->x_gui.x_lab->s_name:"",
-         x->x_gui.x_font, x->x_gui.x_fontsize, sys_fontweight,
-         x->x_gui.x_lcol, x, x, nlet_tag);
-    if (!x->x_gui.x_fsf.x_snd_able && canvas == x->x_gui.x_glist)
-    {
-        sys_vgui(".x%lx.c create prect %d %d %d %d "
-                 "-stroke $pd_colors(iemgui_nlet) "
-                 "-tags {%lxBNG%so%d %so%d %lxBNG outlet iemgui %s}\n",
-            canvas, xpos,
-            ypos + x->x_gui.x_h-1, xpos + IOWIDTH,
-            ypos + x->x_gui.x_h, x, nlet_tag, 0, nlet_tag, 0, x, nlet_tag);
-    }
-    if (!x->x_gui.x_fsf.x_rcv_able && canvas == x->x_gui.x_glist)
-    {
-        sys_vgui(".x%lx.c create prect %d %d %d %d "
-                 "-stroke $pd_colors(iemgui_nlet) "
-                 "-tags {%lxBNG%si%d %si%d %lxBNG inlet iemgui %s}\n",
-            canvas, xpos, ypos,
-            xpos + IOWIDTH, ypos+1, x, nlet_tag, 0, nlet_tag, 0, x, nlet_tag);
-    }
-//}
+    iemgui_label_draw_new(&x->x_gui,canvas,xpos,ypos,nlet_tag,"BNG");
+    bng_draw_io(x,glist,7);
 }
 
 void bng_draw_move(t_bng *x, t_glist *glist)
@@ -132,8 +110,7 @@ void bng_draw_move(t_bng *x, t_glist *glist)
             canvas, x, cx, cy);
         sys_vgui(".x%lx.c itemconfigure %lxBUT -fill #%6.6x -r %f\n",
             canvas, x, x->x_flashed?x->x_gui.x_fcol:x->x_gui.x_bcol, cr);
-        sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",
-            canvas, x, xpos+x->x_gui.x_ldx, ypos+x->x_gui.x_ldy);
+        iemgui_label_draw_move(&x->x_gui,canvas,xpos,ypos);
         if(!x->x_gui.x_fsf.x_snd_able && canvas == x->x_gui.x_glist)
             sys_vgui(".x%lx.c coords %lxBNG%so%d %d %d %d %d\n",
                 canvas, x, nlet_tag, 0, xpos,
@@ -149,37 +126,10 @@ void bng_draw_move(t_bng *x, t_glist *glist)
     }
 }
 
-void bng_draw_erase(t_bng* x, t_glist* glist)
-{
-    t_canvas *canvas=glist_getcanvas(glist);
-    sys_vgui(".x%lx.c delete %lxBNG\n", canvas, x);
-    sys_vgui(".x%lx.c dtag all %lxBNG\n", canvas, x);
-    scalehandle_draw_erase2(&x->x_gui,glist);
-}
-
 void bng_draw_config(t_bng* x, t_glist* glist)
 {
     t_canvas *canvas=glist_getcanvas(glist);
-
-    /*
-    char color[64];
-    if (x->x_gui.x_fsf.x_selected)
-        sprintf(color, "$pd_colors(selection)");
-    else
-        sprintf(color, "#%6.6x", x->x_gui.x_lcol);
-    */
-
-    if (x->x_gui.x_fsf.x_selected && x->x_gui.x_glist == canvas)
-        sys_vgui(".x%lx.c itemconfigure %lxLABEL -font {{%s} -%d %s} "
-                 "-fill $pd_colors(selection) -text {%s} \n",
-             canvas, x, x->x_gui.x_font, x->x_gui.x_fontsize, sys_fontweight,
-             strcmp(x->x_gui.x_lab->s_name, "empty")?x->x_gui.x_lab->s_name:"");
-    else
-        sys_vgui(".x%lx.c itemconfigure %lxLABEL -font {{%s} -%d %s} "
-                 "-fill #%6.6x -text {%s} \n",
-             canvas, x, x->x_gui.x_font, x->x_gui.x_fontsize, sys_fontweight,
-             x->x_gui.x_lcol,
-             strcmp(x->x_gui.x_lab->s_name, "empty")?x->x_gui.x_lab->s_name:"");
+    iemgui_label_draw_config(&x->x_gui,canvas);
     sys_vgui(".x%lx.c itemconfigure %lxBASE -fill #%6.6x\n "
              ".x%lx.c itemconfigure %lxBUT -fill #%6.6x\n",
          canvas, x, x->x_gui.x_bcol, canvas, x,
@@ -188,72 +138,29 @@ void bng_draw_config(t_bng* x, t_glist* glist)
              x->x_flashed?x->x_gui.x_fcol:x->x_gui.x_bcol);*/
 }
 
-void bng_draw_io(t_bng* x, t_glist* glist, int old_snd_rcv_flags)
-{
-    int xpos=text_xpix(&x->x_gui.x_obj, glist);
-    int ypos=text_ypix(&x->x_gui.x_obj, glist);
-    t_canvas *canvas=glist_getcanvas(glist);
-
-    if (glist_isvisible(canvas) && canvas == x->x_gui.x_glist)
-    {
-        char *nlet_tag = iem_get_tag(glist, (t_iemgui *)x);
-        if((old_snd_rcv_flags & IEM_GUI_OLD_SND_FLAG) &&
-            !x->x_gui.x_fsf.x_snd_able)
-            sys_vgui(".x%lx.c create prect %d %d %d %d "
-                     "-stroke $pd_colors(iemgui_nlet) "
-                     "-tags {%lxBNG%so%d %so%d %lxBNG outlet iemgui %s}\n",
-                 canvas, xpos,
-                 ypos + x->x_gui.x_h-1, xpos + IOWIDTH,
-                 ypos + x->x_gui.x_h, x, nlet_tag, 0, nlet_tag, 0, x, nlet_tag);
-        if(!(old_snd_rcv_flags & IEM_GUI_OLD_SND_FLAG) &&
-            x->x_gui.x_fsf.x_snd_able)
-            sys_vgui(".x%lx.c delete %lxBNG%so%d\n", canvas, x, nlet_tag, 0);
-        if((old_snd_rcv_flags & IEM_GUI_OLD_RCV_FLAG) &&
-            !x->x_gui.x_fsf.x_rcv_able)
-            sys_vgui(".x%lx.c create prect %d %d %d %d "
-                     "-stroke $pd_colors(iemgui_nlet) "
-                     "-tags {%lxBNG%si%d %si%d %lxBNG inlet iemgui %s}\n",
-                 canvas, xpos, ypos, xpos + IOWIDTH, ypos+1, x,
-                 nlet_tag, 0, nlet_tag, 0, x, nlet_tag);
-        if(!(old_snd_rcv_flags & IEM_GUI_OLD_RCV_FLAG) &&
-            x->x_gui.x_fsf.x_rcv_able)
-            sys_vgui(".x%lx.c delete %lxBNG%si%d\n", canvas, x, nlet_tag, 0);
-    }
-}
-
 void bng_draw_select(t_bng* x, t_glist* glist)
 {
     t_canvas *canvas=glist_getcanvas(glist);
-    //if (glist_isvisible(canvas)) {
     if(x->x_gui.x_fsf.x_selected)
     {
         /* check if we are drawing inside a gop abstraction visible
            on parent canvas -- if so, disable highlighting */
         if (x->x_gui.x_glist == glist_getcanvas(glist))
         {
-            sys_vgui(".x%lx.c itemconfigure %lxBASE "
-                     "-stroke $pd_colors(selection)\n", canvas, x);
-            sys_vgui(".x%lx.c itemconfigure %lxBUT "
-                     "-stroke $pd_colors(selection)\n", canvas, x);
-            sys_vgui(".x%lx.c itemconfigure %lxLABEL "
-                     "-fill $pd_colors(selection)\n", canvas, x);
+            sys_vgui(".x%lx.c itemconfigure {%lxBASE||%lxBUT} "
+                     "-stroke $pd_colors(selection)\n", canvas, x, x);
             scalehandle_draw_select2(&x->x_gui,glist,"BNG",
                 x->x_gui.x_w-1,x->x_gui.x_h-1);
         }
-        sys_vgui(".x%lx.c addtag selected withtag %lxBNG\n", canvas, x);
     }
     else
     {
-        sys_vgui(".x%lx.c itemconfigure %lxBASE -stroke %s\n",
-            canvas, x, IEM_GUI_COLOR_NORMAL);
-        sys_vgui(".x%lx.c itemconfigure %lxBUT -stroke %s\n",
-            canvas, x, IEM_GUI_COLOR_NORMAL);
-        sys_vgui(".x%lx.c itemconfigure %lxLABEL -fill #%6.6x\n",
-            canvas, x, x->x_gui.x_lcol);
-        sys_vgui(".x%lx.c dtag %lxBNG selected\n", canvas, x);
+        sys_vgui(".x%lx.c itemconfigure {%lxBASE||%lxBUT} -stroke %s\n",
+            canvas, x, x, IEM_GUI_COLOR_NORMAL);
         scalehandle_draw_erase2(&x->x_gui,glist);
     }
-    //}
+    iemgui_label_draw_select(&x->x_gui,canvas);
+    iemgui_tag_selected(&x->x_gui,canvas,"BNG");
 }
 
 static void bng__clickhook(t_scalehandle *sh, t_floatarg f,
@@ -328,7 +235,7 @@ void bng_draw(t_bng *x, t_glist *glist, int mode)
     else if(mode == IEM_GUI_DRAW_MODE_SELECT)
         bng_draw_select(x, glist);
     else if(mode == IEM_GUI_DRAW_MODE_ERASE)
-        bng_draw_erase(x, glist);
+        iemgui_draw_erase(&x->x_gui, glist, "BNG");
     else if(mode == IEM_GUI_DRAW_MODE_CONFIG)
         bng_draw_config(x, glist);
     else if(mode >= IEM_GUI_DRAW_MODE_IO)
@@ -743,16 +650,11 @@ void g_bang_setup(void)
     class_addmethod(scalehandle_class, (t_method)bng__motionhook,
             gensym("_motion"), A_FLOAT, A_FLOAT, 0);
 
-    bng_widgetbehavior.w_getrectfn = bng_getrect;
-    bng_widgetbehavior.w_displacefn = iemgui_displace;
-    bng_widgetbehavior.w_selectfn = iemgui_select;
-    bng_widgetbehavior.w_activatefn = NULL;
-    bng_widgetbehavior.w_deletefn = iemgui_delete;
-    bng_widgetbehavior.w_visfn = iemgui_vis;
-    bng_widgetbehavior.w_clickfn = bng_newclick;
-    bng_widgetbehavior.w_displacefnwtag = iemgui_displace_withtag;
+    wb_init(&bng_widgetbehavior,bng_getrect,bng_newclick);
     class_setwidget(bng_class, &bng_widgetbehavior);
     class_sethelpsymbol(bng_class, gensym("bng"));
     class_setsavefn(bng_class, bng_save);
     class_setpropertiesfn(bng_class, bng_properties);
+    
+    s_empty = gensym("empty");
 }
diff --git a/pd/src/g_graph.c b/pd/src/g_graph.c
index afbf2cc90179bb52e016eb71b96e81167eab2444..3c9473b89ce1f68b324540c46790106420d951d6 100644
--- a/pd/src/g_graph.c
+++ b/pd/src/g_graph.c
@@ -402,13 +402,13 @@ void glist_cleanup(t_glist *x)
     freebytes(x->gl_ylabel, x->gl_nylabels * sizeof(*(x->gl_ylabel)));
     if (x->x_handle)
     {    
-        pd_unbind(x->x_handle, ((t_scalehandle *)x->x_handle)->h_bindsym);
-        pd_free(x->x_handle);
+        pd_unbind((t_pd *)x->x_handle, ((t_scalehandle *)x->x_handle)->h_bindsym);
+        pd_free((t_pd *)x->x_handle);
     }
     if (x->x_mhandle)
     {
-        pd_unbind(x->x_mhandle, ((t_scalehandle *)x->x_mhandle)->h_bindsym);
-        pd_free(x->x_mhandle);
+        pd_unbind((t_pd *)x->x_mhandle, ((t_scalehandle *)x->x_mhandle)->h_bindsym);
+        pd_free((t_pd *)x->x_mhandle);
     }
     gstub_cutoff(x->gl_stub);
 }
diff --git a/pd/src/g_hdial.c b/pd/src/g_hdial.c
index 0d8eb8798a833144b076e89ac7c7053068db4931..067ace9d51db0b6512cc942af4c2a0860ff6aa7b 100644
--- a/pd/src/g_hdial.c
+++ b/pd/src/g_hdial.c
@@ -54,7 +54,11 @@ void hradio_draw_update(t_gobj *client, t_glist *glist)
         x->x_drawn = x->x_on;
     }
 }
-
+void hradio_draw_io(t_hradio* x, t_glist* glist, int old_snd_rcv_flags)
+{
+    t_canvas *canvas=glist_getcanvas(glist);
+    iemgui_io_draw(&x->x_gui,canvas,old_snd_rcv_flags,"HRDO");
+}
 void hradio_draw_new(t_hradio *x, t_glist *glist)
 {
     t_canvas *canvas=glist_getcanvas(glist);
@@ -67,17 +71,15 @@ void hradio_draw_new(t_hradio *x, t_glist *glist)
     scalehandle_draw_new(x->x_gui. x_handle,canvas);
     scalehandle_draw_new(x->x_gui.x_lhandle,canvas);
 
-    //if (glist_isvisible(canvas)) {
-
         char *nlet_tag = iem_get_tag(glist, (t_iemgui *)x);
 
         for(i=0; i<n; i++)
         {
             sys_vgui(".x%lx.c create prect %d %d %d %d "
                      "-stroke $pd_colors(iemgui_border) -fill #%6.6x "
-                     "-tags {%lxBASE%d %lxHRDO %s text iemgui border}\n",
+                     "-tags {%lxBASE%d %lxBASE %lxHRDO %s text iemgui border}\n",
                  canvas, xx11, yy11, xx11+dx, yy12,
-                 x->x_gui.x_bcol, x, i, x, nlet_tag);
+                 x->x_gui.x_bcol, x, i, x, x, nlet_tag);
             sys_vgui(".x%lx.c create prect %d %d %d %d -fill #%6.6x "
                      "-stroke #%6.6x -tags {%lxBUT%d %lxHRDO %s text iemgui}\n",
                  canvas, xx21, yy21, xx22, yy22,
@@ -89,26 +91,8 @@ void hradio_draw_new(t_hradio *x, t_glist *glist)
             xx22 += dx;
             x->x_drawn = x->x_on;
         }
-        sys_vgui(".x%lx.c create text %d %d -text {%s} -anchor w "
-                 "-font {{%s} -%d %s} -fill #%6.6x "
-                 "-tags {%lxLABEL %lxHRDO %s text iemgui}\n",
-             canvas, xx11b+x->x_gui.x_ldx, yy11+x->x_gui.x_ldy,
-             strcmp(x->x_gui.x_lab->s_name, "empty")?x->x_gui.x_lab->s_name:"",
-             x->x_gui.x_font, x->x_gui.x_fontsize, sys_fontweight,
-             x->x_gui.x_lcol, x, x, nlet_tag);
-        if (!x->x_gui.x_fsf.x_snd_able && canvas == x->x_gui.x_glist)
-            sys_vgui(".x%lx.c create prect %d %d %d %d "
-                     "-stroke $pd_colors(iemgui_nlet) "
-                     "-tags {%lxHRDO%so%d %so%d %lxHRDO %s outlet iemgui}\n",
-                 canvas, xx11b, yy12-1, xx11b + IOWIDTH, yy12,
-                 x, nlet_tag, 0, nlet_tag, 0, x, nlet_tag);
-        if (!x->x_gui.x_fsf.x_rcv_able && canvas == x->x_gui.x_glist)
-            sys_vgui(".x%lx.c create prect %d %d %d %d "
-                     "-stroke $pd_colors(iemgui_nlet) "
-                     "-tags {%lxHRDO%si%d %si%d %lxHRDO %s inlet iemgui}\n",
-                 canvas, xx11b, yy11, xx11b + IOWIDTH, yy11+1,
-                 x, nlet_tag, 0, nlet_tag, 0, x, nlet_tag);
-    //}
+    iemgui_label_draw_new(&x->x_gui,canvas,xx11b,yy11,nlet_tag,"HRDO");
+    hradio_draw_io(x,glist,7);
 }
 
 void hradio_draw_move(t_hradio *x, t_glist *glist)
@@ -138,8 +122,7 @@ void hradio_draw_move(t_hradio *x, t_glist *glist)
             xx21 += dx;
             xx22 += dx;
         }
-        sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",
-                 canvas, x, xx11b+x->x_gui.x_ldx, yy11+x->x_gui.x_ldy);
+        iemgui_label_draw_move(&x->x_gui,canvas,xx11b,yy11);
         if(!x->x_gui.x_fsf.x_snd_able && canvas == x->x_gui.x_glist)
             sys_vgui(".x%lx.c coords %lxHRDO%so%d %d %d %d %d\n",
                  canvas, x, nlet_tag, 0, xx11b, yy12-1, xx11b + IOWIDTH, yy12);
@@ -152,39 +135,11 @@ void hradio_draw_move(t_hradio *x, t_glist *glist)
     }
 }
 
-void hradio_draw_erase(t_hradio* x, t_glist* glist)
-{
-    t_canvas *canvas=glist_getcanvas(glist);
-
-    sys_vgui(".x%lx.c delete %lxHRDO\n", canvas, x);
-    sys_vgui(".x%lx.c dtag all %lxHRDO\n", canvas, x);
-    scalehandle_draw_erase2(&x->x_gui,glist);
-}
-
 void hradio_draw_config(t_hradio* x, t_glist* glist)
 {
     t_canvas *canvas=glist_getcanvas(glist);
     int n=x->x_number, i;
-
-    /*
-    char color[64];
-    if (x->x_gui.x_fsf.x_selected)
-        sprintf(color, "$pd_colors(selection)");
-    else
-        sprintf(color, "#%6.6x", x->x_gui.x_lcol);
-    */
-
-    if (x->x_gui.x_fsf.x_selected && x->x_gui.x_glist == canvas)
-        sys_vgui(".x%lx.c itemconfigure %lxLABEL -font {{%s} -%d %s} "
-                 "-fill $pd_colors(selection) -text {%s} \n",
-             canvas, x, x->x_gui.x_font, x->x_gui.x_fontsize, sys_fontweight,
-             strcmp(x->x_gui.x_lab->s_name, "empty")?x->x_gui.x_lab->s_name:"");
-    else
-        sys_vgui(".x%lx.c itemconfigure %lxLABEL -font {{%s} -%d %s} "
-                 "-fill #%6.6x -text {%s} \n",
-             canvas, x, x->x_gui.x_font, x->x_gui.x_fontsize, sys_fontweight,
-             x->x_gui.x_lcol,
-             strcmp(x->x_gui.x_lab->s_name, "empty")?x->x_gui.x_lab->s_name:"");        
+    iemgui_label_draw_config(&x->x_gui,canvas);
     for(i=0; i<n; i++)
     {
         sys_vgui(".x%lx.c itemconfigure %lxBASE%d "
@@ -200,81 +155,29 @@ void hradio_draw_config(t_hradio* x, t_glist* glist)
     }
 }
 
-void hradio_draw_io(t_hradio* x, t_glist* glist, int old_snd_rcv_flags)
-{
-    t_canvas *canvas=glist_getcanvas(glist);
-    int xpos=text_xpix(&x->x_gui.x_obj, glist);
-    int ypos=text_ypix(&x->x_gui.x_obj, glist);
-
-    if (glist_isvisible(canvas) && canvas == x->x_gui.x_glist)
-    {
-
-        char *nlet_tag = iem_get_tag(glist, (t_iemgui *)x);
-
-        if ((old_snd_rcv_flags & IEM_GUI_OLD_SND_FLAG) &&
-           !x->x_gui.x_fsf.x_snd_able)
-            sys_vgui(".x%lx.c create prect %d %d %d %d "
-                     "-stroke $pd_colors(iemgui_nlet) "
-                     "-tags {%lxHRDO%so%d %so%d %lxHRDO %s outlet iemgui}\n",
-                 canvas,
-                 xpos, ypos + x->x_gui.x_w-1,
-                 xpos + IOWIDTH, ypos + x->x_gui.x_w,
-                 x, nlet_tag, 0, nlet_tag, 0, x, nlet_tag);
-        if (!(old_snd_rcv_flags & IEM_GUI_OLD_SND_FLAG) &&
-            x->x_gui.x_fsf.x_snd_able)
-            sys_vgui(".x%lx.c delete %lxHRDO%so%d\n", canvas, x, nlet_tag, 0);
-        if ((old_snd_rcv_flags & IEM_GUI_OLD_RCV_FLAG) &&
-            !x->x_gui.x_fsf.x_rcv_able)
-            sys_vgui(".x%lx.c create prect %d %d %d %d "
-                     "-stroke $pd_colors(iemgui_nlet) "
-                     "-tags {%lxHRDO%si%d %si%d %lxHRDO %s inlet iemgui}\n",
-                 canvas,
-                 xpos, ypos,
-                 xpos + IOWIDTH, ypos+1,
-                 x, nlet_tag, 0, nlet_tag, 0, x, nlet_tag);
-        if (!(old_snd_rcv_flags & IEM_GUI_OLD_RCV_FLAG) &&
-            x->x_gui.x_fsf.x_rcv_able)
-            sys_vgui(".x%lx.c delete %lxHRDO%si%d\n", canvas, x, nlet_tag, 0);
-    }
-}
-
 void hradio_draw_select(t_hradio* x, t_glist* glist)
 {
     t_canvas *canvas=glist_getcanvas(glist);
-    int n=x->x_number, i;
-    //if (glist_isvisible(canvas)) {
-
-        if(x->x_gui.x_fsf.x_selected)
-        {
-            // check if we are drawing inside a gop abstraction
-            // visible on parent canvas.  If so, disable highlighting
-            if (x->x_gui.x_glist == glist_getcanvas(glist))
-            {
-                for(i=0; i<n; i++)
-                {
-                    sys_vgui(".x%lx.c itemconfigure %lxBASE%d "
-                             "-stroke $pd_colors(selection)\n", canvas, x, i);
-                }
-                sys_vgui(".x%lx.c itemconfigure %lxLABEL "
-                         "-fill $pd_colors(selection)\n", canvas, x);
-                scalehandle_draw_select2(&x->x_gui,glist,"HRDO",
-                    x->x_gui.x_w*x->x_number-1,x->x_gui.x_h-1);
-            }
-            sys_vgui(".x%lx.c addtag selected withtag %lxHRDO\n", canvas, x);
-        }
-        else
+    if(x->x_gui.x_fsf.x_selected)
+    {
+        // check if we are drawing inside a gop abstraction
+        // visible on parent canvas.  If so, disable highlighting
+        if (x->x_gui.x_glist == glist_getcanvas(glist))
         {
-            sys_vgui(".x%lx.c dtag %lxHRDO selected\n", canvas, x);
-            for(i=0; i<n; i++)
-            {
-                sys_vgui(".x%lx.c itemconfigure %lxBASE%d -stroke %s\n",
-                    canvas, x, i, IEM_GUI_COLOR_NORMAL);
-            }
-            sys_vgui(".x%lx.c itemconfigure %lxLABEL -fill #%6.6x\n",
-                canvas, x, x->x_gui.x_lcol);
-            scalehandle_draw_erase2(&x->x_gui,glist);
+            sys_vgui(".x%lx.c itemconfigure %lxBASE "
+                "-stroke $pd_colors(selection)\n", canvas, x);
+            scalehandle_draw_select2(&x->x_gui,glist,"HRDO",
+                x->x_gui.x_w*x->x_number-1,x->x_gui.x_h-1);
         }
-    //}
+    }
+    else
+    {
+        sys_vgui(".x%lx.c itemconfigure %lxBASE -stroke %s\n",
+            canvas, x, IEM_GUI_COLOR_NORMAL);
+        scalehandle_draw_erase2(&x->x_gui,glist);
+    }
+    iemgui_label_draw_select(&x->x_gui,canvas);
+    iemgui_tag_selected(&x->x_gui,canvas,"HRDO");
 }
 
 static void hradio__clickhook(t_scalehandle *sh, t_floatarg f, t_floatarg xxx,
@@ -348,7 +251,7 @@ void hradio_draw(t_hradio *x, t_glist *glist, int mode)
     else if(mode == IEM_GUI_DRAW_MODE_SELECT)
         hradio_draw_select(x, glist);
     else if(mode == IEM_GUI_DRAW_MODE_ERASE)
-        hradio_draw_erase(x, glist);
+        iemgui_draw_erase(&x->x_gui, glist, "HRDO");
     else if(mode == IEM_GUI_DRAW_MODE_CONFIG)
         hradio_draw_config(x, glist);
     else if(mode >= IEM_GUI_DRAW_MODE_IO)
@@ -855,14 +758,7 @@ void g_hradio_setup(void)
     class_addmethod(scalehandle_class, (t_method)hradio__motionhook,
             gensym("_motion"), A_FLOAT, A_FLOAT, 0);
 
-    hradio_widgetbehavior.w_getrectfn = hradio_getrect;
-    hradio_widgetbehavior.w_displacefn = iemgui_displace;
-    hradio_widgetbehavior.w_selectfn = iemgui_select;
-    hradio_widgetbehavior.w_activatefn = NULL;
-    hradio_widgetbehavior.w_deletefn = iemgui_delete;
-    hradio_widgetbehavior.w_visfn = iemgui_vis;
-    hradio_widgetbehavior.w_clickfn = hradio_newclick;
-    hradio_widgetbehavior.w_displacefnwtag = iemgui_displace_withtag;
+    wb_init(&hradio_widgetbehavior,hradio_getrect,hradio_newclick);
     class_setwidget(hradio_class, &hradio_widgetbehavior);
     class_sethelpsymbol(hradio_class, gensym("hradio"));
     class_setsavefn(hradio_class, hradio_save);
diff --git a/pd/src/g_hslider.c b/pd/src/g_hslider.c
index 2b780888b38539ee01c85445f0cff5784817f5a9..2519831d198eeb55001e31f8c618481ddbe9785f 100644
--- a/pd/src/g_hslider.c
+++ b/pd/src/g_hslider.c
@@ -70,6 +70,11 @@ static void hslider_draw_update(t_gobj *client, t_glist *glist)
     x->x_gui.x_changed = 0;
 }
 
+static void hslider_draw_io(t_hslider* x,t_glist* glist, int old_snd_rcv_flags)
+{
+    t_canvas *canvas=glist_getcanvas(glist);
+    iemgui_io_draw(&x->x_gui,canvas,old_snd_rcv_flags,"HSLDR");
+}
 static void hslider_draw_new(t_hslider *x, t_glist *glist)
 {
     int xpos=text_xpix(&x->x_gui.x_obj, glist);
@@ -80,8 +85,6 @@ static void hslider_draw_new(t_hslider *x, t_glist *glist)
     scalehandle_draw_new(x->x_gui. x_handle,canvas);
     scalehandle_draw_new(x->x_gui.x_lhandle,canvas);
 
-    //if (glist_isvisible(canvas)) {
-
         char *nlet_tag = iem_get_tag(glist, (t_iemgui *)x);
 
         sys_vgui(".x%lx.c create prect %d %d %d %d "
@@ -94,28 +97,8 @@ static void hslider_draw_new(t_hslider *x, t_glist *glist)
                  "-stroke #%6.6x -tags {%lxKNOB %lxHSLDR %s text iemgui}\n",
              canvas, r, ypos+2, r,
              ypos + x->x_gui.x_h-2, x->x_gui.x_fcol, x, x, nlet_tag);
-        sys_vgui(".x%lx.c create text %d %d -text {%s} -anchor w "
-                 "-font {{%s} -%d %s} -fill #%6.6x "
-                 "-tags {%lxLABEL %lxHSLDR % text iemgui}\n",
-             canvas, xpos+x->x_gui.x_ldx,
-             ypos+x->x_gui.x_ldy,
-             strcmp(x->x_gui.x_lab->s_name, "empty")?x->x_gui.x_lab->s_name:"",
-             x->x_gui.x_font, x->x_gui.x_fontsize, sys_fontweight,
-             x->x_gui.x_lcol, x, x, nlet_tag);
-        if (!x->x_gui.x_fsf.x_snd_able && canvas == x->x_gui.x_glist)
-            sys_vgui(".x%lx.c create prect %d %d %d %d "
-                     "-stroke $pd_colors(iemgui_nlet) "
-                     "-tags {%lxHSLDR%so%d %so%d %lxHSLDR %s outlet iemgui}\n",
-                 canvas, xpos, ypos + x->x_gui.x_h-1,
-                 xpos+7, ypos + x->x_gui.x_h, x, nlet_tag,
-                 0, nlet_tag, 0, x, nlet_tag);
-        if (!x->x_gui.x_fsf.x_rcv_able && canvas == x->x_gui.x_glist)
-            sys_vgui(".x%lx.c create prect %d %d %d %d "
-                     "-stroke $pd_colors(iemgui_nlet) "
-                     "-tags {%lxHSLDR%si%d %si%d %lxHSLDR %s inlet iemgui}\n",
-                 canvas, xpos, ypos,
-                 xpos+7, ypos+1, x, nlet_tag, 0, nlet_tag, 0, x, nlet_tag);
-    //}
+        iemgui_label_draw_new(&x->x_gui,canvas,xpos,ypos,nlet_tag,"HSLDR");
+    hslider_draw_io(x,glist,7);
 }
 
 static void hslider_draw_move(t_hslider *x, t_glist *glist)
@@ -137,8 +120,7 @@ static void hslider_draw_move(t_hslider *x, t_glist *glist)
         sys_vgui(".x%lx.c coords %lxKNOB %d %d %d %d\n",
                  canvas, x, r, ypos+2,
                  r, ypos + x->x_gui.x_h-2);
-        sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",
-                 canvas, x, xpos+x->x_gui.x_ldx, ypos+x->x_gui.x_ldy);
+        iemgui_label_draw_move(&x->x_gui,canvas,xpos,ypos);
         if(!x->x_gui.x_fsf.x_snd_able && canvas == x->x_gui.x_glist)
             sys_vgui(".x%lx.c coords %lxHSLDR%so%d %d %d %d %d\n",
                  canvas, x, nlet_tag, 0,
@@ -157,102 +139,38 @@ static void hslider_draw_move(t_hslider *x, t_glist *glist)
     }
 }
 
-static void hslider_draw_erase(t_hslider* x,t_glist* glist)
-{
-    t_canvas *canvas=glist_getcanvas(glist);
-
-    sys_vgui(".x%lx.c delete %lxHSLDR\n", canvas, x);
-    sys_vgui(".x%lx.c dtag all %lxHSLDR\n", canvas, x);
-    scalehandle_draw_erase2(&x->x_gui,glist);
-}
-
 static void hslider_draw_config(t_hslider* x,t_glist* glist)
 {
     t_canvas *canvas=glist_getcanvas(glist);
-
-    if (x->x_gui.x_fsf.x_selected && x->x_gui.x_glist == canvas)
-        sys_vgui(".x%lx.c itemconfigure %lxLABEL -font {{%s} -%d %s} "
-                 "-fill $pd_colors(selection) -text {%s} \n",
-                 canvas, x, x->x_gui.x_font, x->x_gui.x_fontsize,
-                 sys_fontweight,
-                 strcmp(x->x_gui.x_lab->s_name, "empty") ?
-                     x->x_gui.x_lab->s_name : "");
-    else
-        sys_vgui(".x%lx.c itemconfigure %lxLABEL -font {{%s} -%d %s} "
-                 "-fill #%6.6x -text {%s} \n",
-                 canvas, x, x->x_gui.x_font, x->x_gui.x_fontsize,
-                 sys_fontweight, x->x_gui.x_lcol,
-                 strcmp(x->x_gui.x_lab->s_name, "empty") ?
-                     x->x_gui.x_lab->s_name : "");
+    iemgui_label_draw_config(&x->x_gui,canvas);
     sys_vgui(".x%lx.c itemconfigure %lxKNOB "
              "-stroke #%6.6x\n .x%lx.c itemconfigure %lxBASE -fill #%6.6x\n",
         canvas, x, x->x_gui.x_fcol, canvas, x, x->x_gui.x_bcol);
 }
 
-static void hslider_draw_io(t_hslider* x,t_glist* glist, int old_snd_rcv_flags)
-{
-    int xpos=text_xpix(&x->x_gui.x_obj, glist);
-    int ypos=text_ypix(&x->x_gui.x_obj, glist);
-    t_canvas *canvas=glist_getcanvas(glist);
-
-    if (glist_isvisible(canvas) && canvas == x->x_gui.x_glist)
-    {
-
-        char *nlet_tag = iem_get_tag(glist, (t_iemgui *)x);
-
-        if ((old_snd_rcv_flags & IEM_GUI_OLD_SND_FLAG) &&
-            !x->x_gui.x_fsf.x_snd_able)
-            sys_vgui(".x%lx.c create prect %d %d %d %d "
-                     "-stroke $pd_colors(iemgui_nlet) "
-                     "-tags {%lxHSLDR%so%d %so%d %lxHSLDR %s outlet iemgui}\n",
-                 canvas, xpos, ypos + x->x_gui.x_h-1,
-                 xpos+7, ypos + x->x_gui.x_h, x, nlet_tag,
-                 0, nlet_tag, 0, x, nlet_tag);
-        if (!(old_snd_rcv_flags & IEM_GUI_OLD_SND_FLAG) &&
-            x->x_gui.x_fsf.x_snd_able)
-            sys_vgui(".x%lx.c delete %lxHSLDR%so%d\n", canvas, x, nlet_tag, 0);
-        if ((old_snd_rcv_flags & IEM_GUI_OLD_RCV_FLAG) &&
-            !x->x_gui.x_fsf.x_rcv_able)
-            sys_vgui(".x%lx.c create prect %d %d %d %d "
-                     "-stroke $pd_colors(iemgui_nlet) "
-                     "-tags {%lxHSLDR%si%d %si%d %lxHSLDR %s inlet iemgui}\n",
-                 canvas, xpos, ypos,
-                 xpos+7, ypos+1, x, nlet_tag, 0, nlet_tag, 0, x, nlet_tag);
-        if(!(old_snd_rcv_flags & IEM_GUI_OLD_RCV_FLAG) &&
-           x->x_gui.x_fsf.x_rcv_able)
-            sys_vgui(".x%lx.c delete %lxHSLDR%si%d\n", canvas, x, nlet_tag, 0);
-    }
-}
-
 static void hslider_draw_select(t_hslider* x,t_glist* glist)
 {
     t_canvas *canvas=glist_getcanvas(glist);
-    //if (glist_isvisible(canvas)) {
-        if(x->x_gui.x_fsf.x_selected)
-        {
-            // check if we are drawing inside a gop abstraction
-            // visible on parent canvas. If so, disable highlighting
-            if (x->x_gui.x_glist == glist_getcanvas(glist))
-            {
-                sys_vgui(".x%lx.c itemconfigure %lxBASE "
-                         "-stroke $pd_colors(selection)\n", canvas, x);
-                sys_vgui(".x%lx.c itemconfigure %lxLABEL "
-                         "-fill $pd_colors(selection)\n", canvas, x);
-                scalehandle_draw_select2(&x->x_gui,glist,"HSLDR",
-                    x->x_gui.x_w+5-1,x->x_gui.x_h-1);
-            }
-            sys_vgui(".x%lx.c addtag selected withtag %lxHSLDR\n", canvas, x);
-        }
-        else
+    if(x->x_gui.x_fsf.x_selected)
+    {
+        // check if we are drawing inside a gop abstraction
+        // visible on parent canvas. If so, disable highlighting
+        if (x->x_gui.x_glist == glist_getcanvas(glist))
         {
-            sys_vgui(".x%lx.c itemconfigure %lxBASE -stroke %s\n",
-                canvas, x, IEM_GUI_COLOR_NORMAL);
-            sys_vgui(".x%lx.c itemconfigure %lxLABEL -fill #%6.6x\n",
-                canvas, x, x->x_gui.x_lcol);
-            sys_vgui(".x%lx.c dtag %lxHSLDR selected\n", canvas, x);
-            scalehandle_draw_erase2(&x->x_gui,glist);
+            sys_vgui(".x%lx.c itemconfigure %lxBASE "
+                     "-stroke $pd_colors(selection)\n", canvas, x);
+            scalehandle_draw_select2(&x->x_gui,glist,"HSLDR",
+                x->x_gui.x_w+5-1,x->x_gui.x_h-1);
         }
-    //}
+    }
+    else
+    {
+        sys_vgui(".x%lx.c itemconfigure %lxBASE -stroke %s\n",
+            canvas, x, IEM_GUI_COLOR_NORMAL);
+        scalehandle_draw_erase2(&x->x_gui,glist);
+    }
+    iemgui_label_draw_select(&x->x_gui,canvas);
+    iemgui_tag_selected(&x->x_gui,canvas,"HSLDR");
 }
 
 void hslider_check_minmax(t_hslider *x, double min, double max);
@@ -336,7 +254,7 @@ void hslider_draw(t_hslider *x, t_glist *glist, int mode)
     else if(mode == IEM_GUI_DRAW_MODE_SELECT)
         hslider_draw_select(x, glist);
     else if(mode == IEM_GUI_DRAW_MODE_ERASE)
-        hslider_draw_erase(x, glist);
+        iemgui_draw_erase(&x->x_gui, glist, "HSLDR");
     else if(mode == IEM_GUI_DRAW_MODE_CONFIG)
         hslider_draw_config(x, glist);
     else if(mode >= IEM_GUI_DRAW_MODE_IO)
@@ -867,14 +785,7 @@ void g_hslider_setup(void)
     class_addmethod(scalehandle_class, (t_method)hslider__motionhook,
             gensym("_motion"), A_FLOAT, A_FLOAT, 0);
 
-    hslider_widgetbehavior.w_getrectfn =    hslider_getrect;
-    hslider_widgetbehavior.w_displacefn =   iemgui_displace;
-    hslider_widgetbehavior.w_selectfn =     iemgui_select;
-    hslider_widgetbehavior.w_activatefn =   NULL;
-    hslider_widgetbehavior.w_deletefn =     iemgui_delete;
-    hslider_widgetbehavior.w_visfn =        iemgui_vis;
-    hslider_widgetbehavior.w_clickfn =      hslider_newclick;
-    hslider_widgetbehavior.w_displacefnwtag = iemgui_displace_withtag;
+    wb_init(&hslider_widgetbehavior,hslider_getrect,hslider_newclick);
     class_setwidget(hslider_class, &hslider_widgetbehavior);
     class_sethelpsymbol(hslider_class, gensym("hslider"));
     class_setsavefn(hslider_class, hslider_save);
diff --git a/pd/src/g_mycanvas.c b/pd/src/g_mycanvas.c
index c75243efd5ce30fa2e757d4c5398677ffe5aa236..9f769be2b36a5814066c51522763078189c3c46d 100644
--- a/pd/src/g_mycanvas.c
+++ b/pd/src/g_mycanvas.c
@@ -44,7 +44,6 @@ void my_canvas_draw_new(t_my_canvas *x, t_glist *glist)
     scalehandle_draw_new(x->x_gui. x_handle,canvas);
     scalehandle_draw_new(x->x_gui.x_lhandle,canvas);
 
-    //if (glist_isvisible(glist) {
         char *nlet_tag = iem_get_tag(glist, (t_iemgui *)x);
 
         sys_vgui(".x%lx.c create prect %d %d %d %d -fill #%6.6x -stroke #%6.6x "
@@ -57,14 +56,7 @@ void my_canvas_draw_new(t_my_canvas *x, t_glist *glist)
                  canvas, xpos, ypos,
                  xpos + x->x_gui.x_w, ypos + x->x_gui.x_h,
                  x->x_gui.x_bcol, x, x, nlet_tag);
-        sys_vgui(".x%lx.c create text %d %d -text {%s} -anchor w "
-                 "-font {{%s} -%d %s} -fill #%6.6x "
-                 "-tags {%lxLABEL %lxMYCNV %s text iemgui}\n",
-                 canvas, xpos+x->x_gui.x_ldx, ypos+x->x_gui.x_ldy,
-                 strcmp(x->x_gui.x_lab->s_name, "empty")?x->x_gui.x_lab->s_name:"",
-                 x->x_gui.x_font, x->x_gui.x_fontsize, sys_fontweight,
-                 x->x_gui.x_lcol, x, x, nlet_tag);
-    //}
+    iemgui_label_draw_new(&x->x_gui,canvas,xpos,ypos,nlet_tag,"MYCNV");
 }
 
 void my_canvas_draw_move(t_my_canvas *x, t_glist *glist)
@@ -82,9 +74,7 @@ void my_canvas_draw_move(t_my_canvas *x, t_glist *glist)
         sys_vgui(".x%lx.c coords %lxBASE %d %d %d %d\n",
                  canvas, x, xpos, ypos,
                  xpos + x->x_gui.x_w, ypos + x->x_gui.x_h);
-        sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",
-                 canvas, x, xpos+x->x_gui.x_ldx,
-                 ypos+x->x_gui.x_ldy);
+        iemgui_label_draw_move(&x->x_gui,canvas,xpos,ypos);
         /* redraw scale handle rectangle if selected */
         if (x->x_gui.x_fsf.x_selected)
         {
@@ -93,70 +83,46 @@ void my_canvas_draw_move(t_my_canvas *x, t_glist *glist)
     }
 }
 
-void my_canvas_draw_erase(t_my_canvas* x, t_glist* glist)
-{
-    t_canvas *canvas=glist_getcanvas(glist);
-
-    sys_vgui(".x%lx.c delete %lxMYCNV\n", canvas, x);
-    sys_vgui(".x%lx.c dtag all %lxMYCNV\n", canvas, x);
-    scalehandle_draw_erase2(&x->x_gui,glist);
-}
-
 void my_canvas_draw_config(t_my_canvas* x, t_glist* glist)
 {
     t_canvas *canvas=glist_getcanvas(glist);
-
-    /*
-    char color[64];
-    if (x->x_gui.x_fsf.x_selected)
-        sprintf(color, "$pd_colors(selection)");
-    else
-        sprintf(color, "#%6.6x", x->x_gui.x_bcol);
-    */
-
     sys_vgui(".x%lx.c itemconfigure %lxRECT -fill #%6.6x -stroke #%6.6x\n",
              canvas, x, x->x_gui.x_bcol, x->x_gui.x_bcol);
     if (x->x_gui.x_fsf.x_selected && x->x_gui.x_glist == canvas)
         sys_vgui(".x%lx.c itemconfigure %lxBASE "
-                 "-stroke $pd_colors(selection)\n",
-                 canvas, x);
+                 "-stroke $pd_colors(selection)\n", canvas, x);
     else
         sys_vgui(".x%lx.c itemconfigure %lxBASE -stroke #%6.6x\n", canvas, x,
              x->x_gui.x_bcol);
-    sys_vgui(".x%lx.c itemconfigure %lxLABEL -font {{%s} -%d %s} "
-             "-fill #%6.6x -text {%s} \n",
-             canvas, x, x->x_gui.x_font, x->x_gui.x_fontsize, sys_fontweight,
-             x->x_gui.x_lcol,
-             strcmp(x->x_gui.x_lab->s_name, "empty")?x->x_gui.x_lab->s_name:"");
+    iemgui_label_draw_config(&x->x_gui,canvas);
 }
 
 void my_canvas_draw_select(t_my_canvas* x, t_glist* glist)
 {
     t_canvas *canvas=glist_getcanvas(glist);
-    //if (glist_isvisible(canvas)) {
-        if(x->x_gui.x_fsf.x_selected)
-        {
-            // check if we are drawing inside a gop abstraction
-            // visible on parent canvas
-            // if so, disable highlighting
-            if (x->x_gui.x_glist == glist_getcanvas(glist))
-            {
-                char *nlet_tag = iem_get_tag(glist, (t_iemgui *)x);
-                sys_vgui(".x%lx.c itemconfigure %lxBASE "
-                         "-stroke $pd_colors(selection)\n", canvas, x);
-                scalehandle_draw_select2(&x->x_gui,glist,"MYCNV",
-                    x->x_vis_w,x->x_vis_h);
-            }
-            sys_vgui(".x%lx.c addtag selected withtag %lxMYCNV\n", canvas, x);
-        }
-        else
+    if(x->x_gui.x_fsf.x_selected)
+    {
+        // check if we are drawing inside a gop abstraction
+        // visible on parent canvas
+        // if so, disable highlighting
+        if (x->x_gui.x_glist == glist_getcanvas(glist))
         {
-            sys_vgui(".x%lx.c itemconfigure %lxBASE -stroke #%6.6x\n",
-                canvas, x, x->x_gui.x_bcol);
-            sys_vgui(".x%lx.c dtag %lxMYCNV selected\n", canvas, x);
-            scalehandle_draw_erase2(&x->x_gui,glist);
+            sys_vgui(".x%lx.c itemconfigure %lxBASE "
+                     "-stroke $pd_colors(selection)\n", canvas, x);
+            scalehandle_draw_select2(&x->x_gui,glist,"MYCNV",
+                x->x_vis_w,x->x_vis_h);
         }
-    //}
+        sys_vgui(".x%lx.c addtag selected withtag %lxMYCNV\n", canvas, x);
+    }
+    else
+    {
+        sys_vgui(".x%lx.c itemconfigure %lxBASE -stroke #%6.6x\n",
+            canvas, x, x->x_gui.x_bcol);
+        sys_vgui(".x%lx.c dtag %lxMYCNV selected\n", canvas, x);
+        scalehandle_draw_erase2(&x->x_gui,glist);
+    }
+    iemgui_label_draw_select(&x->x_gui,canvas);
+    iemgui_tag_selected(&x->x_gui,canvas,"MYCNV");
 }
 
 static void my_canvas__clickhook(t_scalehandle *sh, t_floatarg f,
@@ -236,7 +202,7 @@ void my_canvas_draw(t_my_canvas *x, t_glist *glist, int mode)
     else if(mode == IEM_GUI_DRAW_MODE_SELECT)
         my_canvas_draw_select(x, glist);
     else if(mode == IEM_GUI_DRAW_MODE_ERASE)
-        my_canvas_draw_erase(x, glist);
+        iemgui_draw_erase(&x->x_gui, glist, "MYCNV");
     else if(mode == IEM_GUI_DRAW_MODE_CONFIG)
         my_canvas_draw_config(x, glist);
 }
@@ -553,14 +519,7 @@ void g_mycanvas_setup(void)
     class_addmethod(scalehandle_class, (t_method)my_canvas__motionhook,
             gensym("_motion"), A_FLOAT, A_FLOAT, 0);
 
-    my_canvas_widgetbehavior.w_getrectfn = my_canvas_getrect;
-    my_canvas_widgetbehavior.w_displacefn = iemgui_displace;
-    my_canvas_widgetbehavior.w_selectfn = iemgui_select;
-    my_canvas_widgetbehavior.w_activatefn = NULL;
-    my_canvas_widgetbehavior.w_deletefn = iemgui_delete;
-    my_canvas_widgetbehavior.w_visfn = iemgui_vis;
-    my_canvas_widgetbehavior.w_clickfn = NULL;
-    my_canvas_widgetbehavior.w_displacefnwtag = iemgui_displace_withtag;
+    wb_init(&my_canvas_widgetbehavior,my_canvas_getrect,0);
     class_setwidget(my_canvas_class, &my_canvas_widgetbehavior);
     class_sethelpsymbol(my_canvas_class, gensym("my_canvas"));
     class_setsavefn(my_canvas_class, my_canvas_save);
diff --git a/pd/src/g_numbox.c b/pd/src/g_numbox.c
index bced2fdbc1559cb0dd564b79320ea496066898dc..272d1b62fd8e7b7b98917676ccb81d6d179d30e9 100644
--- a/pd/src/g_numbox.c
+++ b/pd/src/g_numbox.c
@@ -189,6 +189,12 @@ static void my_numbox_draw_update(t_gobj *client, t_glist *glist)
     x->x_gui.x_changed = 0;
 }
 
+static void my_numbox_draw_io(t_my_numbox* x,t_glist* glist,
+    int old_snd_rcv_flags)
+{
+    t_canvas *canvas=glist_getcanvas(glist);
+    iemgui_io_draw(&x->x_gui,canvas,old_snd_rcv_flags,"NUM");
+}
 static void my_numbox_draw_new(t_my_numbox *x, t_glist *glist)
 {
     int half=x->x_gui.x_h/2, d=1+x->x_gui.x_h/34;
@@ -215,22 +221,7 @@ static void my_numbox_draw_new(t_my_numbox *x, t_glist *glist)
                      xpos + x->x_numwidth, ypos + x->x_gui.x_h,
                      xpos, ypos + x->x_gui.x_h,
                      IEM_GUI_COLOR_NORMAL, x->x_gui.x_bcol, x, x, nlet_tag);
-            if(!x->x_gui.x_fsf.x_snd_able && canvas == x->x_gui.x_glist)
-                sys_vgui(".x%lx.c create prect %d %d %d %d "
-                         "-stroke $pd_colors(iemgui_nlet) "
-                         "-tags {%lxNUM%so%d %so%d %lxNUM %s outlet iemgui}\n",
-                     canvas,
-                     xpos, ypos + x->x_gui.x_h-1,
-                     xpos+IOWIDTH, ypos + x->x_gui.x_h,
-                     x, nlet_tag, 0, nlet_tag, 0, x, nlet_tag);
-            if(!x->x_gui.x_fsf.x_rcv_able && canvas == x->x_gui.x_glist)
-                sys_vgui(".x%lx.c create prect %d %d %d %d "
-                         "-stroke $pd_colors(iemgui_nlet) "
-                         "-tags {%lxNUM%si%d %si%d %lxNUM %s inlet iemgui}\n",
-                     canvas,
-                     xpos, ypos,
-                     xpos+IOWIDTH, ypos+1,
-                     x, nlet_tag, 0, nlet_tag, 0, x, nlet_tag);
+            my_numbox_draw_io(x,glist,7);
         }
         else
         {
@@ -251,13 +242,7 @@ static void my_numbox_draw_new(t_my_numbox *x, t_glist *glist)
                 xpos + half, ypos + half,
                 xpos, ypos + x->x_gui.x_h,
                 x->x_gui.x_fcol, x, x, nlet_tag);
-        sys_vgui(".x%lx.c create text %d %d -text {%s} -anchor w "
-                 "-font {{%s} -%d %s} -fill #%6.6x "
-                 "-tags {%lxLABEL %lxNUM %s text iemgui}\n",
-            canvas, xpos+x->x_gui.x_ldx, ypos+x->x_gui.x_ldy,
-            strcmp(x->x_gui.x_lab->s_name, "empty")?x->x_gui.x_lab->s_name:"",
-            x->x_gui.x_font, x->x_gui.x_fontsize, sys_fontweight,
-                 x->x_gui.x_lcol, x, x, nlet_tag);
+        iemgui_label_draw_new(&x->x_gui,canvas,xpos,ypos,nlet_tag,"NUM");
         my_numbox_ftoa(x);
         sys_vgui(".x%lx.c create text %d %d -text {%s} -anchor w "
                  "-font {{%s} -%d %s} -fill #%6.6x "
@@ -304,8 +289,7 @@ static void my_numbox_draw_move(t_my_numbox *x, t_glist *glist)
                      canvas, x, xpos, ypos,
                      xpos + half, ypos + half,
                      xpos, ypos + x->x_gui.x_h);
-        sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",
-                 canvas, x, xpos+x->x_gui.x_ldx, ypos+x->x_gui.x_ldy);
+        iemgui_label_draw_move(&x->x_gui,canvas,xpos,ypos);
         sys_vgui(".x%lx.c coords %lxNUMBER %d %d\n",
                  canvas, x, xpos+half+2, ypos+half+d);
         /* redraw scale handle rectangle if selected */
@@ -314,52 +298,21 @@ static void my_numbox_draw_move(t_my_numbox *x, t_glist *glist)
     }
 }
 
-static void my_numbox_draw_erase(t_my_numbox* x,t_glist* glist)
-{
-    t_canvas *canvas=glist_getcanvas(glist);
-
-    sys_vgui(".x%lx.c delete %lxNUM\n", canvas, x);
-    sys_vgui(".x%lx.c dtag all %lxNUM\n", canvas, x);
-    scalehandle_draw_erase2(&x->x_gui,glist);
-}
-
 static void my_numbox_draw_config(t_my_numbox* x,t_glist* glist)
 {
     t_canvas *canvas=glist_getcanvas(glist);
-
-    /*
-    char color[64];
-    char lcolor[64];
-    if (x->x_gui.x_fsf.x_selected)
-    {
-        sprintf(color, "$pd_colors(selection)");
-        sprintf(lcolor, "$pd_colors(selection)");
-    }
-    else
-    {
-        sprintf(color, "#%6.6x", x->x_gui.x_fcol);
-        sprintf(lcolor, "#%6.6x", x->x_gui.x_lcol);
-    }
-    */
-
     if (x->x_gui.x_fsf.x_selected && x->x_gui.x_glist == canvas)
     {
-        sys_vgui(".x%lx.c itemconfigure %lxLABEL -font {{%s} -%d %s} "
-                 "-fill $pd_colors(selection) -text {%s} \n "
-                 ".x%lx.c itemconfigure %lxNUMBER -font {{%s} -%d %s} "
-                 "-fill $pd_colors(selection) \n "
+        sys_vgui(".x%lx.c itemconfigure %lxNUMBER -font {{%s} -%d %s} "
+                 "-fill $pd_colors(selection)\n"
                  ".x%lx.c itemconfigure %lxBASE2 "
                  "-stroke $pd_colors(selection)\n",
                  canvas, x, x->x_gui.x_font,
                  x->x_gui.x_fontsize, sys_fontweight,
-                 strcmp(
-                     x->x_gui.x_lab->s_name, "empty")?x->x_gui.x_lab->s_name:"",
-                 canvas, x, x->x_gui.x_font,
-                 x->x_gui.x_fontsize, sys_fontweight,
                  canvas,x);
         /*
         sys_vgui(".x%lx.c itemconfigure %lxNUMBER -font {{%s} %d %s} "
-                 "-fill $pd_colors(selection) \n",
+                 "-fill $pd_colors(selection)\n",
                  canvas, x, x->x_gui.x_font,
                  x->x_gui.x_fontsize, sys_fontweight);
         sys_vgui(".x%lx.c itemconfigure %lxBASE2 -fill $pd_colors(selection)\n",
@@ -368,18 +321,11 @@ static void my_numbox_draw_config(t_my_numbox* x,t_glist* glist)
     }
     else
     {
-        sys_vgui(".x%lx.c itemconfigure %lxLABEL -font {{%s} -%d %s} "
-                 "-fill #%6.6x -text {%s} \n "
-                 ".x%lx.c itemconfigure %lxNUMBER -font {{%s} -%d %s} "
+        sys_vgui(".x%lx.c itemconfigure %lxNUMBER -font {{%s} -%d %s} "
                  "-fill #%6.6x \n .x%lx.c itemconfigure %lxBASE2 "
                  "-stroke #%6.6x\n",
                  canvas, x, x->x_gui.x_font,
                  x->x_gui.x_fontsize, sys_fontweight,
-                 x->x_gui.x_lcol,
-                 strcmp(
-                     x->x_gui.x_lab->s_name, "empty")?x->x_gui.x_lab->s_name:"",
-                 canvas, x, x->x_gui.x_font,
-                 x->x_gui.x_fontsize, sys_fontweight,
                  x->x_gui.x_fcol, canvas, x, x->x_gui.x_fcol);
 
         /*sys_vgui(".x%lx.c itemconfigure %lxNUMBER -font {{%s} %d %s} "
@@ -392,96 +338,52 @@ static void my_numbox_draw_config(t_my_numbox* x,t_glist* glist)
                  x, x->x_gui.x_fcol);*/
 
     }
+    iemgui_label_draw_config(&x->x_gui,canvas);
     sys_vgui(".x%lx.c itemconfigure %lxBASE1 -fill #%6.6x;\n", canvas,
              x, x->x_gui.x_bcol);
 }
 
-static void my_numbox_draw_io(t_my_numbox* x,t_glist* glist,
-    int old_snd_rcv_flags)
-{
-    int xpos=text_xpix(&x->x_gui.x_obj, glist);
-    int ypos=text_ypix(&x->x_gui.x_obj, glist);
-    t_canvas *canvas=glist_getcanvas(glist);
-
-    if (glist_isvisible(canvas) && canvas == x->x_gui.x_glist)
-    {
-
-        char *nlet_tag = iem_get_tag(glist, (t_iemgui *)x);
-
-        if((old_snd_rcv_flags & IEM_GUI_OLD_SND_FLAG) &&
-            !x->x_gui.x_fsf.x_snd_able)
-            sys_vgui(".x%lx.c create prect %d %d %d %d "
-                     "-stroke $pd_colors(iemgui_nlet) "
-                     "-tags {%lxNUM%so%d %so%d %lxNUM %s outlet iemgui}\n",
-                 canvas,
-                 xpos, ypos + x->x_gui.x_h-1,
-                 xpos+IOWIDTH, ypos + x->x_gui.x_h,
-                 x, nlet_tag, 0, nlet_tag, 0, x, nlet_tag);
-        if(!(old_snd_rcv_flags & IEM_GUI_OLD_SND_FLAG)
-            && x->x_gui.x_fsf.x_snd_able)
-            sys_vgui(".x%lx.c delete %lxNUM%so%d\n", canvas, x, nlet_tag, 0);
-        if((old_snd_rcv_flags & IEM_GUI_OLD_RCV_FLAG) &&
-            !x->x_gui.x_fsf.x_rcv_able)
-            sys_vgui(".x%lx.c create prect %d %d %d %d "
-                     "-stroke $pd_colors(iemgui_nlet) "
-                     "-tags {%lxNUM%si%d %si%d %lxNUM %s inlet iemgui}\n",
-                 canvas,
-                 xpos, ypos,
-                 xpos+IOWIDTH, ypos+1,
-                 x, nlet_tag, 0, nlet_tag, 0, x, nlet_tag);
-        if(!(old_snd_rcv_flags & IEM_GUI_OLD_RCV_FLAG) &&
-            x->x_gui.x_fsf.x_rcv_able)
-            sys_vgui(".x%lx.c delete %lxNUM%si%d\n", canvas, x, nlet_tag, 0);
-    }
-}
-
 static void my_numbox_draw_select(t_my_numbox *x, t_glist *glist)
 {
     t_canvas *canvas=glist_getcanvas(glist);
-    //if (glist_isvisible(canvas)) {
-        if(x->x_gui.x_fsf.x_selected)
+    if(x->x_gui.x_fsf.x_selected)
+    {
+        if(x->x_gui.x_fsf.x_change)
         {
-            if(x->x_gui.x_fsf.x_change)
-            {
-                x->x_gui.x_fsf.x_change = 0;
-                clock_unset(x->x_clock_reset);
-                x->x_buf[0] = 0;
-                sys_queuegui(x, x->x_gui.x_glist, my_numbox_draw_update);
-            }
-            // check if we are drawing inside a gop abstraction
-            // visible on parent canvas
-            // if so, disable highlighting
-            if (x->x_gui.x_glist == glist_getcanvas(glist))
-            {
-                char *nlet_tag = iem_get_tag(glist, (t_iemgui *)x);
-                sys_vgui(".x%lx.c itemconfigure {%lxBASE1||%lxBASE2} "
-                         "-stroke $pd_colors(selection)\n", canvas, x, x);
-                sys_vgui(".x%lx.c itemconfigure {%lxLABEL||%lxNUMBER} "
-                         "-fill $pd_colors(selection)\n", canvas, x, x);
-                scalehandle_draw_select2(&x->x_gui,glist,"NUM",
-                    x->x_numwidth-1,x->x_gui.x_h-1);
-            }
-            sys_vgui(".x%lx.c addtag selected withtag %lxNUM\n", canvas, x);
+            x->x_gui.x_fsf.x_change = 0;
+            clock_unset(x->x_clock_reset);
+            x->x_buf[0] = 0;
+            sys_queuegui(x, x->x_gui.x_glist, my_numbox_draw_update);
         }
-        else
+        // check if we are drawing inside a gop abstraction
+        // visible on parent canvas
+        // if so, disable highlighting
+        if (x->x_gui.x_glist == glist_getcanvas(glist))
         {
-            sys_vgui(".x%lx.c dtag %lxNUM selected\n", canvas, x);
-
-            if (x->x_hide_frame <= 1)
-                sys_vgui(".x%lx.c itemconfigure %lxBASE1 -stroke %s\n",
-                    canvas, x, IEM_GUI_COLOR_NORMAL);
-            else sys_vgui(".x%lx.c itemconfigure %lxBASE1 -stroke #%6.6x\n",
-                    canvas, x, x->x_gui.x_bcol);
-
-            sys_vgui(".x%lx.c itemconfigure %lxBASE2 -stroke #%6.6x\n",
-                canvas, x, x->x_gui.x_fcol);
-            sys_vgui(".x%lx.c itemconfigure %lxLABEL -fill #%6.6x\n",
-                canvas, x, x->x_gui.x_lcol);
-            sys_vgui(".x%lx.c itemconfigure %lxNUMBER -fill #%6.6x\n",
-                canvas, x, x->x_gui.x_fcol);
-            scalehandle_draw_erase2(&x->x_gui,glist);
+            sys_vgui(".x%lx.c itemconfigure {%lxBASE1||%lxBASE2} "
+                     "-stroke $pd_colors(selection)\n", canvas, x, x);
+            sys_vgui(".x%lx.c itemconfigure %lxNUMBER "
+                     "-fill $pd_colors(selection)\n", canvas, x);
+            scalehandle_draw_select2(&x->x_gui,glist,"NUM",
+                x->x_numwidth-1,x->x_gui.x_h-1);
         }
-    //}
+    }
+    else
+    {
+        if (x->x_hide_frame <= 1)
+            sys_vgui(".x%lx.c itemconfigure %lxBASE1 -stroke %s\n",
+                canvas, x, IEM_GUI_COLOR_NORMAL);
+        else sys_vgui(".x%lx.c itemconfigure %lxBASE1 -stroke #%6.6x\n",
+                canvas, x, x->x_gui.x_bcol);
+
+        sys_vgui(".x%lx.c itemconfigure %lxBASE2 -stroke #%6.6x\n",
+            canvas, x, x->x_gui.x_fcol);
+        sys_vgui(".x%lx.c itemconfigure %lxNUMBER -fill #%6.6x\n",
+            canvas, x, x->x_gui.x_fcol);
+        scalehandle_draw_erase2(&x->x_gui,glist);
+    }
+    iemgui_label_draw_select(&x->x_gui,canvas);
+    iemgui_tag_selected(&x->x_gui,canvas,"NUM");
 }
 
 static void my_numbox__clickhook(t_scalehandle *sh, t_floatarg f,
@@ -593,7 +495,7 @@ void my_numbox_draw(t_my_numbox *x, t_glist *glist, int mode)
     else if(mode == IEM_GUI_DRAW_MODE_SELECT)
         my_numbox_draw_select(x, glist);
     else if(mode == IEM_GUI_DRAW_MODE_ERASE)
-        my_numbox_draw_erase(x, glist);
+        iemgui_draw_erase(&x->x_gui, glist, "NUM");
     else if(mode == IEM_GUI_DRAW_MODE_CONFIG)
         my_numbox_draw_config(x, glist);
     else if(mode >= IEM_GUI_DRAW_MODE_IO)
@@ -1212,15 +1114,7 @@ void g_numbox_setup(void)
         gensym("log_height"), A_FLOAT, 0);
     class_addmethod(my_numbox_class, (t_method)my_numbox_hide_frame,
         gensym("hide_frame"), A_FLOAT, 0);
-    my_numbox_widgetbehavior.w_getrectfn =    my_numbox_getrect;
-    my_numbox_widgetbehavior.w_displacefn =   iemgui_displace;
-    my_numbox_widgetbehavior.w_selectfn =     iemgui_select;
-    my_numbox_widgetbehavior.w_activatefn =   NULL;
-    my_numbox_widgetbehavior.w_deletefn =     iemgui_delete;
-    my_numbox_widgetbehavior.w_visfn =        iemgui_vis;
-    my_numbox_widgetbehavior.w_clickfn =      my_numbox_newclick;
-    my_numbox_widgetbehavior.w_displacefnwtag = iemgui_displace_withtag;
- 
+
     scalehandle_class = class_new(gensym("_scalehandle"), 0, 0,
                   sizeof(t_scalehandle), CLASS_PD, 0);
     class_addmethod(scalehandle_class, (t_method)my_numbox__clickhook,
@@ -1228,6 +1122,7 @@ void g_numbox_setup(void)
     class_addmethod(scalehandle_class, (t_method)my_numbox__motionhook,
             gensym("_motion"), A_FLOAT, A_FLOAT, 0);
 
+    wb_init(&my_numbox_widgetbehavior,my_numbox_getrect,my_numbox_newclick);
     class_setwidget(my_numbox_class, &my_numbox_widgetbehavior);
     class_sethelpsymbol(my_numbox_class, gensym("numbox2"));
     class_setsavefn(my_numbox_class, my_numbox_save);
diff --git a/pd/src/g_toggle.c b/pd/src/g_toggle.c
index 067b6c33be518971ab18a2cce05be42a572d3db2..03a00c193ccaae55d3774e77cf9258de666b0ed7 100644
--- a/pd/src/g_toggle.c
+++ b/pd/src/g_toggle.c
@@ -54,6 +54,12 @@ void toggle_draw_update(t_gobj *xgobj, t_glist *glist)
     }
 }
 
+void toggle_draw_io(t_toggle* x, t_glist* glist, int old_snd_rcv_flags)
+{
+    t_canvas *canvas=glist_getcanvas(glist);
+    iemgui_io_draw(&x->x_gui,canvas,old_snd_rcv_flags,"TGL");
+}
+
 void toggle_draw_new(t_toggle *x, t_glist *glist)
 {
     t_canvas *canvas=glist_getcanvas(glist);
@@ -63,8 +69,6 @@ void toggle_draw_new(t_toggle *x, t_glist *glist)
     scalehandle_draw_new(x->x_gui. x_handle,canvas);
     scalehandle_draw_new(x->x_gui.x_lhandle,canvas);
 
-    //if (glist_isvisible(canvas)) {
-
         char *nlet_tag = iem_get_tag(glist, (t_iemgui *)x);
 
         if(x->x_gui.x_w >= 30)
@@ -89,28 +93,8 @@ void toggle_draw_new(t_toggle *x, t_glist *glist)
                  canvas, xx+w+1, yy + x->x_gui.x_h-w-1,
                  xx + x->x_gui.x_w-w-1, yy+w+1, w,
                  (x->x_on!=0.0)?x->x_gui.x_fcol:x->x_gui.x_bcol, x, x, nlet_tag);
-        sys_vgui(".x%lx.c create text %d %d -text {%s} -anchor w "
-                 "-font {{%s} -%d %s} -fill #%6.6x "
-                 "-tags {%lxLABEL %lxTGL %s text iemgui}\n",
-                 canvas, xx+x->x_gui.x_ldx,
-                 yy+x->x_gui.x_ldy,
-                 strcmp(x->x_gui.x_lab->s_name, "empty")?x->x_gui.x_lab->s_name:"",
-                 x->x_gui.x_font, x->x_gui.x_fontsize, sys_fontweight,
-                 x->x_gui.x_lcol, x, x, nlet_tag);
-        if(!x->x_gui.x_fsf.x_snd_able && canvas == x->x_gui.x_glist)
-            sys_vgui(".x%lx.c create prect %d %d %d %d "
-                     "-stroke $pd_colors(iemgui_nlet) "
-                     "-tags {%lxTGL%so%d %so%d %lxTGL %s outlet iemgui}\n",
-                 canvas, xx, yy + x->x_gui.x_h-1,
-                 xx + IOWIDTH, yy + x->x_gui.x_h,
-                 x, nlet_tag, 0, nlet_tag, 0, x, nlet_tag);
-        if(!x->x_gui.x_fsf.x_rcv_able && canvas == x->x_gui.x_glist)
-            sys_vgui(".x%lx.c create prect %d %d %d %d "
-                     "-stroke $pd_colors(iemgui_nlet) "
-                     "-tags {%lxTGL%si%d %si%d %lxTGL %s inlet iemgui}\n",
-                 canvas, xx, yy, xx + IOWIDTH, yy+1,
-                 x, nlet_tag, 0, nlet_tag, 0, x, nlet_tag);
-    //}
+        iemgui_label_draw_new(&x->x_gui,canvas,xx,yy,nlet_tag,"TGL");
+    toggle_draw_io(x,glist,7);
 }
 
 void toggle_draw_move(t_toggle *x, t_glist *glist)
@@ -139,8 +123,7 @@ void toggle_draw_move(t_toggle *x, t_glist *glist)
         sys_vgui(".x%lx.c coords %lxX2 %d %d %d %d\n",
                  canvas, x, xx+w+1,
                  yy + x->x_gui.x_h-w-1, xx + x->x_gui.x_w-w-1, yy+w+1);
-        sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",
-                 canvas, x, xx+x->x_gui.x_ldx, yy+x->x_gui.x_ldy);
+        iemgui_label_draw_move(&x->x_gui,canvas,xx,yy);
         if(!x->x_gui.x_fsf.x_snd_able && canvas == x->x_gui.x_glist)
             sys_vgui(".x%lx.c coords %lxTGL%so%d %d %d %d %d\n",
                  canvas, x, nlet_tag, 0, xx,
@@ -154,47 +137,10 @@ void toggle_draw_move(t_toggle *x, t_glist *glist)
     }
 }
 
-void toggle_draw_erase(t_toggle* x, t_glist* glist)
-{
-    t_canvas *canvas=glist_getcanvas(glist);
-
-    sys_vgui(".x%lx.c delete %lxTGL\n", canvas, x);
-    sys_vgui(".x%lx.c dtag all %lxTGL\n", canvas, x);
-    scalehandle_draw_erase2(&x->x_gui,glist);
-}
-
 void toggle_draw_config(t_toggle* x, t_glist* glist)
 {
     t_canvas *canvas=glist_getcanvas(glist);
-
-    /*
-    char color[64];
-    if (x->x_gui.x_fsf.x_selected)
-        sprintf(color, "$pd_colors(selection)");
-    else
-        sprintf(color, "#%6.6x", x->x_gui.x_lcol); 
-
-    sys_vgui(".x%lx.c itemconfigure %lxLABEL -font {{%s} %d %s} "
-             "-fill %s -text {%s} \n",
-             canvas, x, x->x_gui.x_font, x->x_gui.x_fontsize, sys_fontweight,
-             color,
-             strcmp(x->x_gui.x_lab->s_name, "empty")?x->x_gui.x_lab->s_name:"");
-    */
-    if (x->x_gui.x_fsf.x_selected && x->x_gui.x_glist == canvas)
-    {
-        sys_vgui(".x%lx.c itemconfigure %lxLABEL -font {{%s} -%d %s} "
-                 "-fill $pd_colors(selection) -text {%s} \n",
-             canvas, x, x->x_gui.x_font, x->x_gui.x_fontsize, sys_fontweight,
-             strcmp(x->x_gui.x_lab->s_name, "empty")?x->x_gui.x_lab->s_name:"");
-    }
-    else
-    {
-        sys_vgui(".x%lx.c itemconfigure %lxLABEL -font {{%s} -%d %s} "
-                 "-fill #%6.6x -text {%s} \n",
-             canvas, x, x->x_gui.x_font, x->x_gui.x_fontsize, sys_fontweight,
-             x->x_gui.x_lcol,
-             strcmp(x->x_gui.x_lab->s_name, "empty")?x->x_gui.x_lab->s_name:"");
-    }
+    iemgui_label_draw_config(&x->x_gui,canvas);
     sys_vgui(".x%lx.c itemconfigure %lxBASE -fill #%6.6x\n "
              ".x%lx.c itemconfigure %lxX1 -stroke #%6.6x\n "
              ".x%lx.c itemconfigure %lxX2 -stroke #%6.6x\n",
@@ -209,71 +155,30 @@ void toggle_draw_config(t_toggle* x, t_glist* glist)
     */
 }
 
-void toggle_draw_io(t_toggle* x, t_glist* glist, int old_snd_rcv_flags)
-{
-    int xpos=text_xpix(&x->x_gui.x_obj, glist);
-    int ypos=text_ypix(&x->x_gui.x_obj, glist);
-    t_canvas *canvas=glist_getcanvas(glist);
-
-    if (glist_isvisible(canvas) && canvas == x->x_gui.x_glist)
-    {
-        char *nlet_tag = iem_get_tag(glist, (t_iemgui *)x);
-
-        if((old_snd_rcv_flags & IEM_GUI_OLD_SND_FLAG) &&
-            !x->x_gui.x_fsf.x_snd_able)
-            sys_vgui(".x%lx.c create prect %d %d %d %d "
-                     "-stroke $pd_colors(iemgui_nlet) "
-                     "-tags {%lxTGL%so%d %so%d %lxTGL %s outlet iemgui}\n",
-                 canvas, xpos,
-                 ypos + x->x_gui.x_h-1, xpos + IOWIDTH,
-                 ypos + x->x_gui.x_h, x, nlet_tag, 0, nlet_tag, 0, x, nlet_tag);
-        if(!(old_snd_rcv_flags & IEM_GUI_OLD_SND_FLAG) &&
-            x->x_gui.x_fsf.x_snd_able)
-            sys_vgui(".x%lx.c delete %lxTGL%so%d\n", canvas, x, nlet_tag, 0);
-        if((old_snd_rcv_flags & IEM_GUI_OLD_RCV_FLAG) &&
-            !x->x_gui.x_fsf.x_rcv_able)
-            sys_vgui(".x%lx.c create prect %d %d %d %d "
-                     "-stroke $pd_colors(iemgui_nlet) "
-                     "-tags {%lxTGL%si%d %si%d %lxTGL %s inlet iemgui}\n",
-                 canvas, xpos, ypos,
-                 xpos + IOWIDTH, ypos+1, x,
-                 nlet_tag, 0, nlet_tag, 0, x, nlet_tag);
-        if(!(old_snd_rcv_flags & IEM_GUI_OLD_RCV_FLAG) &&
-            x->x_gui.x_fsf.x_rcv_able)
-            sys_vgui(".x%lx.c delete %lxTGL%si%d\n", canvas, x, nlet_tag, 0);
-    }
-}
-
 void toggle_draw_select(t_toggle* x, t_glist* glist)
 {
     t_canvas *canvas=glist_getcanvas(glist);
-    //if (glist_isvisible(canvas)) {
-        if(x->x_gui.x_fsf.x_selected)
-        {
-            // check if we are drawing inside a gop abstraction
-            // visible on parent canvas
-            // if so, disable highlighting
-            if (x->x_gui.x_glist == glist_getcanvas(glist))
-            {
-                sys_vgui(".x%lx.c itemconfigure %lxBASE "
-                         "-stroke $pd_colors(selection)\n", canvas, x);
-                sys_vgui(".x%lx.c itemconfigure %lxLABEL "
-                         "-fill $pd_colors(selection)\n", canvas, x);
-                scalehandle_draw_select2(&x->x_gui,glist,"TGL",
-                    x->x_gui.x_w-1,x->x_gui.x_h-1);
-            }
-            sys_vgui(".x%lx.c addtag selected withtag %lxTGL\n", canvas, x);
-        }
-        else
+    if(x->x_gui.x_fsf.x_selected)
+    {
+        // check if we are drawing inside a gop abstraction
+        // visible on parent canvas
+        // if so, disable highlighting
+        if (x->x_gui.x_glist == glist_getcanvas(glist))
         {
-            sys_vgui(".x%lx.c itemconfigure %lxBASE -stroke %s\n",
-                canvas, x, IEM_GUI_COLOR_NORMAL);
-            sys_vgui(".x%lx.c itemconfigure %lxLABEL -fill #%6.6x\n",
-                canvas, x, x->x_gui.x_lcol);
-            sys_vgui(".x%lx.c dtag %lxTGL selected\n", canvas, x);
-            scalehandle_draw_erase2(&x->x_gui,glist);
+            sys_vgui(".x%lx.c itemconfigure %lxBASE "
+                     "-stroke $pd_colors(selection)\n", canvas, x);
+            scalehandle_draw_select2(&x->x_gui,glist,"TGL",
+                x->x_gui.x_w-1,x->x_gui.x_h-1);
         }
-    //}
+    }
+    else
+    {
+        sys_vgui(".x%lx.c itemconfigure %lxBASE -stroke %s\n",
+            canvas, x, IEM_GUI_COLOR_NORMAL);
+        scalehandle_draw_erase2(&x->x_gui,glist);
+    }
+    iemgui_label_draw_select(&x->x_gui,canvas);
+    iemgui_tag_selected(&x->x_gui,canvas,"TGL");
 }
 
 static void toggle__clickhook(t_scalehandle *sh, t_floatarg f,
@@ -348,7 +253,7 @@ void toggle_draw(t_toggle *x, t_glist *glist, int mode)
     else if(mode == IEM_GUI_DRAW_MODE_SELECT)
         toggle_draw_select(x, glist);
     else if(mode == IEM_GUI_DRAW_MODE_ERASE)
-        toggle_draw_erase(x, glist);
+        iemgui_draw_erase(&x->x_gui, glist, "TGL");
     else if(mode == IEM_GUI_DRAW_MODE_CONFIG)
         toggle_draw_config(x, glist);
     else if(mode >= IEM_GUI_DRAW_MODE_IO)
@@ -684,14 +589,7 @@ void g_toggle_setup(void)
     class_addmethod(scalehandle_class, (t_method)toggle__motionhook,
             gensym("_motion"), A_FLOAT, A_FLOAT, 0);
 
-    toggle_widgetbehavior.w_getrectfn = toggle_getrect;
-    toggle_widgetbehavior.w_displacefn = iemgui_displace;
-    toggle_widgetbehavior.w_selectfn = iemgui_select;
-    toggle_widgetbehavior.w_activatefn = NULL;
-    toggle_widgetbehavior.w_deletefn = iemgui_delete;
-    toggle_widgetbehavior.w_visfn = iemgui_vis;
-    toggle_widgetbehavior.w_clickfn = toggle_newclick;
-    toggle_widgetbehavior.w_displacefnwtag = iemgui_displace_withtag;
+    wb_init(&toggle_widgetbehavior,toggle_getrect,toggle_newclick);
     class_setwidget(toggle_class, &toggle_widgetbehavior);
     class_sethelpsymbol(toggle_class, gensym("toggle"));
     class_setsavefn(toggle_class, toggle_save);
diff --git a/pd/src/g_vdial.c b/pd/src/g_vdial.c
index f324a287216c4a73f323a5963343b89992426ece..ceb72f226b0ea57c74cdaf22fea5b31751216d9b 100644
--- a/pd/src/g_vdial.c
+++ b/pd/src/g_vdial.c
@@ -52,6 +52,12 @@ void vradio_draw_update(t_gobj *client, t_glist *glist)
     }
 }
 
+void vradio_draw_io(t_vradio* x, t_glist* glist, int old_snd_rcv_flags)
+{
+    t_canvas *canvas=glist_getcanvas(glist);
+    iemgui_io_draw(&x->x_gui,canvas,old_snd_rcv_flags,"VRDO");
+}
+
 void vradio_draw_new(t_vradio *x, t_glist *glist)
 {
     t_canvas *canvas=glist_getcanvas(glist);
@@ -65,17 +71,15 @@ void vradio_draw_new(t_vradio *x, t_glist *glist)
     scalehandle_draw_new(x->x_gui. x_handle,canvas);
     scalehandle_draw_new(x->x_gui.x_lhandle,canvas);
 
-    //if (glist_isvisible(canvas)) {
-
         char *nlet_tag = iem_get_tag(glist, (t_iemgui *)x);
 
         for(i=0; i<n; i++)
         {
             sys_vgui(".x%lx.c create prect %d %d %d %d "
                      "-stroke $pd_colors(iemgui_border) -fill #%6.6x "
-                     "-tags {%lxBASE%d %lxVRDO %s text iemgui border}\n",
+                     "-tags {%lxBASE%d %lxBASE %lxVRDO %s text iemgui border}\n",
                  canvas, xx11, yy11, xx12, yy12,
-                 x->x_gui.x_bcol, x, i, x, nlet_tag);
+                 x->x_gui.x_bcol, x, i, x, x, nlet_tag);
             sys_vgui(".x%lx.c create prect %d %d %d %d -fill #%6.6x "
                      "-stroke #%6.6x -tags {%lxBUT%d %lxVRDO %s text iemgui}\n",
                  canvas, xx21, yy21, xx22, yy22,
@@ -88,26 +92,8 @@ void vradio_draw_new(t_vradio *x, t_glist *glist)
             yy22 += dy;
             x->x_drawn = x->x_on;
         }
-        sys_vgui(".x%lx.c create text %d %d -text {%s} -anchor w "
-                 "-font {{%s} -%d %s} -fill #%6.6x "
-                 "-tags {%lxLABEL %lxVRDO %s text iemgui}\n",
-             canvas, xx11+x->x_gui.x_ldx, yy11b+x->x_gui.x_ldy,
-             strcmp(x->x_gui.x_lab->s_name, "empty")?x->x_gui.x_lab->s_name:"",
-             x->x_gui.x_font, x->x_gui.x_fontsize, sys_fontweight,
-             x->x_gui.x_lcol, x, x, nlet_tag);
-        if(!x->x_gui.x_fsf.x_snd_able && canvas == x->x_gui.x_glist)
-            sys_vgui(".x%lx.c create prect %d %d %d %d "
-                     "-stroke $pd_colors(iemgui_nlet) "
-                     "-tags {%lxVRDO%so%d %so%d %lxVRDO %s outlet iemgui}\n",
-                 canvas, xx11, yy11-1, xx11 + IOWIDTH, yy11,
-                 x, nlet_tag, 0, nlet_tag, 0, x, nlet_tag);
-        if(!x->x_gui.x_fsf.x_rcv_able && canvas == x->x_gui.x_glist)
-            sys_vgui(".x%lx.c create prect %d %d %d %d "
-                     "-stroke $pd_colors(iemgui_nlet) "
-                     "-tags {%lxVRDO%si%d %si%d %lxVRDO %s inlet iemgui}\n",
-                 canvas, xx11, yy11b, xx11 + IOWIDTH, yy11b+1,
-                 x, nlet_tag, 0, nlet_tag, 0, x, nlet_tag);
-    //}
+        iemgui_label_draw_new(&x->x_gui,canvas,xx11,yy11b,nlet_tag,"VRDO");
+    vradio_draw_io(x,glist,7);
 }
 
 void vradio_draw_move(t_vradio *x, t_glist *glist)
@@ -136,8 +122,7 @@ void vradio_draw_move(t_vradio *x, t_glist *glist)
             yy21 += dy;
             yy22 += dy;
         }
-        sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",
-                 canvas, x, xx11+x->x_gui.x_ldx, yy11b+x->x_gui.x_ldy);
+        iemgui_label_draw_move(&x->x_gui,canvas,xx11,yy11b);
         if(!x->x_gui.x_fsf.x_snd_able && canvas == x->x_gui.x_glist)
             sys_vgui(".x%lx.c coords %lxVRDO%so%d %d %d %d %d\n",
                  canvas, x, nlet_tag, 0, xx11, yy11-1, xx11 + IOWIDTH, yy11);
@@ -150,39 +135,11 @@ void vradio_draw_move(t_vradio *x, t_glist *glist)
     }
 }
 
-void vradio_draw_erase(t_vradio* x, t_glist* glist)
-{
-    t_canvas *canvas=glist_getcanvas(glist);
-    sys_vgui(".x%lx.c delete %lxVRDO\n", canvas, x);
-    sys_vgui(".x%lx.c dtag all %lxVRDO\n", canvas, x);
-    scalehandle_draw_erase2(&x->x_gui,glist);
-}
-
 void vradio_draw_config(t_vradio* x, t_glist* glist)
 {
     t_canvas *canvas=glist_getcanvas(glist);
     int n=x->x_number, i;
-
-    /*
-    char color[64];
-    if (x->x_gui.x_fsf.x_selected)
-        sprintf(color, "$pd_colors(selection)");
-    else
-        sprintf(color, "#%6.6x", x->x_gui.x_lcol);
-    */
-
-    if (x->x_gui.x_fsf.x_selected && x->x_gui.x_glist == canvas)
-        sys_vgui(".x%lx.c itemconfigure %lxLABEL -font {{%s} -%d %s} "
-                 "-fill $pd_colors(selection) -text {%s} \n",
-             canvas, x, x->x_gui.x_font, x->x_gui.x_fontsize, sys_fontweight,
-             strcmp(x->x_gui.x_lab->s_name, "empty")?x->x_gui.x_lab->s_name:"");
-    else
-        sys_vgui(".x%lx.c itemconfigure %lxLABEL -font {{%s} -%d %s} "
-                 "-fill #%6.6x -text {%s} \n",
-             canvas, x, x->x_gui.x_font, x->x_gui.x_fontsize, sys_fontweight, 
-             x->x_gui.x_lcol,
-             strcmp(x->x_gui.x_lab->s_name, "empty") ?
-                 x->x_gui.x_lab->s_name : "");
+    iemgui_label_draw_config(&x->x_gui,canvas);
     for(i=0; i<n; i++)
     {
         sys_vgui(".x%lx.c itemconfigure %lxBASE%d "
@@ -202,82 +159,29 @@ void vradio_draw_config(t_vradio* x, t_glist* glist)
     }
 }
 
-void vradio_draw_io(t_vradio* x, t_glist* glist, int old_snd_rcv_flags)
-{
-    t_canvas *canvas=glist_getcanvas(glist);
-    int xpos=text_xpix(&x->x_gui.x_obj, glist);
-    int ypos=text_ypix(&x->x_gui.x_obj, glist);
-
-    if (glist_isvisible(canvas) && canvas == x->x_gui.x_glist)
-    {
-
-        char *nlet_tag = iem_get_tag(glist, (t_iemgui *)x);
-
-        if((old_snd_rcv_flags & IEM_GUI_OLD_SND_FLAG) &&
-           !x->x_gui.x_fsf.x_snd_able)
-            sys_vgui(".x%lx.c create prect %d %d %d %d "
-                     "-stroke $pd_colors(iemgui_nlet) "
-                     "-tags {%lxVRDO%so%d %so%d %lxVRDO %s outlet iemgui}\n",
-                     canvas, xpos,
-                     ypos+(x->x_number*x->x_gui.x_h)-1,
-                     xpos+ IOWIDTH,
-                     ypos+(x->x_number*x->x_gui.x_h),
-                     x, nlet_tag, 0, nlet_tag, 0, x, nlet_tag);
-        if(!(old_snd_rcv_flags & IEM_GUI_OLD_SND_FLAG) &&
-           x->x_gui.x_fsf.x_snd_able)
-            sys_vgui(".x%lx.c delete %lxVRDO%so%d\n", canvas, x, nlet_tag, 0);
-        if((old_snd_rcv_flags & IEM_GUI_OLD_RCV_FLAG) &&
-            !x->x_gui.x_fsf.x_rcv_able)
-            sys_vgui(".x%lx.c create prect %d %d %d %d "
-                     "-stroke $pd_colors(iemgui_nlet) "
-                     "-tags {%lxVRDO%si%d %si%d %lxVRDO %s inlet iemgui}\n",
-                     canvas, xpos, ypos,
-                     xpos+ IOWIDTH, ypos+1,
-                     x, nlet_tag, 0, nlet_tag, 0, x, nlet_tag);
-        if(!(old_snd_rcv_flags & IEM_GUI_OLD_RCV_FLAG) &&
-            x->x_gui.x_fsf.x_rcv_able)
-            sys_vgui(".x%lx.c delete %lxVRDO%si%d\n", canvas, x, nlet_tag, 0);
-    }
-}
-
 void vradio_draw_select(t_vradio* x, t_glist* glist)
 {
     t_canvas *canvas=glist_getcanvas(glist);
-    int n=x->x_number, i;
-    //if (glist_isvisible(canvas)) {
-        if(x->x_gui.x_fsf.x_selected)
-        {
-            /* check if we are drawing inside a gop abstraction visible
-               on parent canvas. If so, disable highlighting */
-            if (x->x_gui.x_glist == glist_getcanvas(glist))
-            {
-                char *nlet_tag = iem_get_tag(glist, (t_iemgui *)x);
-                for(i=0; i<n; i++)
-                {
-                    sys_vgui(".x%lx.c itemconfigure %lxBASE%d "
-                             "-stroke $pd_colors(selection)\n", canvas, x, i);
-                }
-                sys_vgui(".x%lx.c itemconfigure %lxLABEL "
-                         "-fill $pd_colors(selection)\n", canvas, x);
-                scalehandle_draw_select2(&x->x_gui,glist,"VRDO",
-                    x->x_gui.x_w-1,x->x_gui.x_h*x->x_number-1);
-            }
-
-            sys_vgui(".x%lx.c addtag selected withtag %lxVRDO\n", canvas, x);
-        }
-        else
+    if(x->x_gui.x_fsf.x_selected)
+    {
+        /* check if we are drawing inside a gop abstraction visible
+           on parent canvas. If so, disable highlighting */
+        if (x->x_gui.x_glist == glist_getcanvas(glist))
         {
-            for(i=0; i<n; i++)
-            {
-                sys_vgui(".x%lx.c dtag %lxVRDO selected\n", canvas, x);
-                sys_vgui(".x%lx.c itemconfigure %lxBASE%d -stroke %s\n",
-                    canvas, x, i, IEM_GUI_COLOR_NORMAL);
-            }
-            sys_vgui(".x%lx.c itemconfigure %lxLABEL -fill #%6.6x\n",
-                canvas, x, x->x_gui.x_lcol);
-            scalehandle_draw_erase2(&x->x_gui,glist);
+            sys_vgui(".x%lx.c itemconfigure %lxBASE "
+                "-stroke $pd_colors(selection)\n", canvas, x);
+            scalehandle_draw_select2(&x->x_gui,glist,"VRDO",
+                x->x_gui.x_w-1,x->x_gui.x_h*x->x_number-1);
         }
-    //}
+    }
+    else
+    {
+        sys_vgui(".x%lx.c itemconfigure %lxBASE -stroke %s\n",
+            canvas, x, IEM_GUI_COLOR_NORMAL);
+        scalehandle_draw_erase2(&x->x_gui,glist);
+    }
+    iemgui_label_draw_select(&x->x_gui,canvas);
+    iemgui_tag_selected(&x->x_gui,canvas,"VRDO");
 }
 
 static void vradio__clickhook(t_scalehandle *sh, t_floatarg f, t_floatarg xxx,
@@ -351,7 +255,7 @@ void vradio_draw(t_vradio *x, t_glist *glist, int mode)
     else if(mode == IEM_GUI_DRAW_MODE_SELECT)
         vradio_draw_select(x, glist);
     else if(mode == IEM_GUI_DRAW_MODE_ERASE)
-        vradio_draw_erase(x, glist);
+        iemgui_draw_erase(&x->x_gui, glist, "VRDO");
     else if(mode == IEM_GUI_DRAW_MODE_CONFIG)
         vradio_draw_config(x, glist);
     else if(mode >= IEM_GUI_DRAW_MODE_IO)
@@ -851,14 +755,7 @@ void g_vradio_setup(void)
     class_addmethod(scalehandle_class, (t_method)vradio__motionhook,
             gensym("_motion"), A_FLOAT, A_FLOAT, 0);
 
-    vradio_widgetbehavior.w_getrectfn = vradio_getrect;
-    vradio_widgetbehavior.w_displacefn = iemgui_displace;
-    vradio_widgetbehavior.w_selectfn = iemgui_select;
-    vradio_widgetbehavior.w_activatefn = NULL;
-    vradio_widgetbehavior.w_deletefn = iemgui_delete;
-    vradio_widgetbehavior.w_visfn = iemgui_vis;
-    vradio_widgetbehavior.w_clickfn = vradio_newclick;
-    vradio_widgetbehavior.w_displacefnwtag = iemgui_displace_withtag;
+    wb_init(&vradio_widgetbehavior,vradio_getrect,vradio_newclick);
     class_setwidget(vradio_class, &vradio_widgetbehavior);
     class_sethelpsymbol(vradio_class, gensym("vradio"));
     class_setsavefn(vradio_class, vradio_save);
diff --git a/pd/src/g_vslider.c b/pd/src/g_vslider.c
index 91b3d25d3dca95c4a21f8648b74ab7351f747a38..9d924a06c5785c25e248bd932ea9ff7f8e4f25e7 100644
--- a/pd/src/g_vslider.c
+++ b/pd/src/g_vslider.c
@@ -72,6 +72,12 @@ static void vslider_draw_update(t_gobj *client, t_glist *glist)
     x->x_gui.x_changed = 0;
 }
 
+static void vslider_draw_io(t_vslider* x,t_glist* glist, int old_snd_rcv_flags)
+{
+    t_canvas *canvas=glist_getcanvas(glist);
+    iemgui_io_draw(&x->x_gui,canvas,old_snd_rcv_flags,"VSLDR");
+}
+
 static void vslider_draw_new(t_vslider *x, t_glist *glist)
 {
     int xpos=text_xpix(&x->x_gui.x_obj, glist);
@@ -82,8 +88,6 @@ static void vslider_draw_new(t_vslider *x, t_glist *glist)
     scalehandle_draw_new(x->x_gui. x_handle,canvas);
     scalehandle_draw_new(x->x_gui.x_lhandle,canvas);
 
-    //if (glist_isvisible(canvas)) {
-
         char *nlet_tag = iem_get_tag(glist, (t_iemgui *)x);
 
         sys_vgui(".x%lx.c create prect %d %d %d %d "
@@ -96,30 +100,8 @@ static void vslider_draw_new(t_vslider *x, t_glist *glist)
                  "-stroke #%6.6x -tags {%lxKNOB %lxVSLDR %s text iemgui}\n",
              canvas, xpos+2, r,
              xpos + x->x_gui.x_w-2, r, x->x_gui.x_fcol, x, x, nlet_tag);
-        sys_vgui(".x%lx.c create text %d %d -text {%s} -anchor w "
-                 "-font {{%s} -%d %s} -fill #%6.6x "
-                 "-tags {%lxLABEL %lxVSLDR %s text iemgui}\n",
-             canvas, xpos+x->x_gui.x_ldx, ypos+x->x_gui.x_ldy,
-             strcmp(x->x_gui.x_lab->s_name, "empty")?x->x_gui.x_lab->s_name:"",
-             x->x_gui.x_font, x->x_gui.x_fontsize, sys_fontweight, 
-             x->x_gui.x_lcol, x, x, nlet_tag);
-        if (!x->x_gui.x_fsf.x_snd_able && canvas == x->x_gui.x_glist)
-            sys_vgui(".x%lx.c create prect %d %d %d %d "
-                     "-stroke $pd_colors(iemgui_nlet) "
-                     "-tags {%lxVSLDR%so%d %so%d %lxVSLDR %s outlet iemgui}\n",
-                 canvas,
-                 xpos, ypos + x->x_gui.x_h+4,
-                 xpos+7, ypos + x->x_gui.x_h+5,
-                 x, nlet_tag, 0, nlet_tag, 0, x, nlet_tag);
-        if (!x->x_gui.x_fsf.x_rcv_able && canvas == x->x_gui.x_glist)
-            sys_vgui(".x%lx.c create prect %d %d %d %d "
-                     "-stroke $pd_colors(iemgui_nlet) "
-                     "-tags {%lxVSLDR%si%d %si%d %lxVSLDR %s inlet iemgui}\n",
-                 canvas,
-                 xpos, ypos,
-                 xpos+7, ypos+1,
-                 x, nlet_tag, 0, nlet_tag, 0, x, nlet_tag);
-    //}
+        iemgui_label_draw_new(&x->x_gui,canvas,xpos,ypos,nlet_tag,"VSLDR");
+    vslider_draw_io(x,glist,7);
 }
 
 static void vslider_draw_move(t_vslider *x, t_glist *glist)
@@ -141,8 +123,7 @@ static void vslider_draw_move(t_vslider *x, t_glist *glist)
         sys_vgui(".x%lx.c coords %lxKNOB %d %d %d %d\n",
                  canvas, x, xpos+2, r,
                  xpos + x->x_gui.x_w-2, r);
-        sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",
-                 canvas, x, xpos+x->x_gui.x_ldx, ypos+x->x_gui.x_ldy);
+        iemgui_label_draw_move(&x->x_gui,canvas,xpos,ypos);
         if(!x->x_gui.x_fsf.x_snd_able && canvas == x->x_gui.x_glist)
             sys_vgui(".x%lx.c coords %lxVSLDR%so%d %d %d %d %d\n",
                  canvas, x, nlet_tag, 0,
@@ -161,40 +142,10 @@ static void vslider_draw_move(t_vslider *x, t_glist *glist)
     }
 }
 
-static void vslider_draw_erase(t_vslider* x,t_glist* glist)
-{
-    t_canvas *canvas=glist_getcanvas(glist);
-
-    sys_vgui(".x%lx.c delete %lxVSLDR\n", canvas, x);
-    sys_vgui(".x%lx.c dtag all %lxVSLDR\n", canvas, x);
-    scalehandle_draw_erase2(&x->x_gui,glist);
-}
-
 static void vslider_draw_config(t_vslider* x,t_glist* glist)
 {
     t_canvas *canvas=glist_getcanvas(glist);
-
-    /*
-    char color[64];
-    if (x->x_gui.x_fsf.x_selected)
-        sprintf(color, "$pd_colors(selection)");
-    else
-        sprintf(color, "#%6.6x", x->x_gui.x_lcol);
-    */
-
-    if (x->x_gui.x_fsf.x_selected && x->x_gui.x_glist == canvas)
-        sys_vgui(".x%lx.c itemconfigure %lxLABEL -font {{%s} -%d %s} "
-                 "-fill $pd_colors(selection) -text {%s} \n",
-                 canvas, x, x->x_gui.x_font, x->x_gui.x_fontsize,
-                 sys_fontweight, 
-                 strcmp(x->x_gui.x_lab->s_name, "empty") ?
-                     x->x_gui.x_lab->s_name : "");
-    else
-        sys_vgui(".x%lx.c itemconfigure %lxLABEL -font {{%s} -%d %s} "
-                 "-fill #%6.6x -text {%s} \n",
-             canvas, x, x->x_gui.x_font, x->x_gui.x_fontsize, sys_fontweight, 
-             x->x_gui.x_lcol,
-             strcmp(x->x_gui.x_lab->s_name, "empty")?x->x_gui.x_lab->s_name:"");
+    iemgui_label_draw_config(&x->x_gui,canvas);
     sys_vgui(".x%lx.c itemconfigure %lxKNOB "
              "-stroke #%6.6x\n .x%lx.c itemconfigure %lxBASE -fill #%6.6x\n",
          canvas, x, x->x_gui.x_fcol, canvas, x, x->x_gui.x_bcol);
@@ -202,73 +153,29 @@ static void vslider_draw_config(t_vslider* x,t_glist* glist)
              x, x->x_gui.x_bcol);*/
 }
 
-static void vslider_draw_io(t_vslider* x,t_glist* glist, int old_snd_rcv_flags)
-{
-    int xpos=text_xpix(&x->x_gui.x_obj, glist);
-    int ypos=text_ypix(&x->x_gui.x_obj, glist);
-    t_canvas *canvas=glist_getcanvas(glist);
-
-    if (glist_isvisible(canvas) && canvas == x->x_gui.x_glist)
-    {
-
-        char *nlet_tag = iem_get_tag(glist, (t_iemgui *)x);
-
-        if((old_snd_rcv_flags & IEM_GUI_OLD_SND_FLAG) &&
-           !x->x_gui.x_fsf.x_snd_able)
-            sys_vgui(".x%lx.c create prect %d %d %d %d "
-                     "-stroke $pd_colors(iemgui_nlet) "
-                     "-tags {%lxVSLDR%so%d %so%d %lxVSLDR %s outlet iemgui}\n",
-                 canvas,
-                 xpos, ypos + x->x_gui.x_h+4,
-                 xpos+7, ypos + x->x_gui.x_h+5,
-                 x, nlet_tag, 0, nlet_tag, 0, x, nlet_tag);
-        if (!(old_snd_rcv_flags & IEM_GUI_OLD_SND_FLAG) &&
-            x->x_gui.x_fsf.x_snd_able)
-            sys_vgui(".x%lx.c delete %lxVSLDR%so%d\n", canvas, x, nlet_tag, 0);
-        if ((old_snd_rcv_flags & IEM_GUI_OLD_RCV_FLAG) &&
-            !x->x_gui.x_fsf.x_rcv_able)
-            sys_vgui(".x%lx.c create prect %d %d %d %d "
-                     "-stroke $pd_colors(iemgui_nlet) "
-                     "-tags {%lxVSLDR%si%d %si%d %lxVSLDR %s inlet iemgui}\n",
-                 canvas,
-                 xpos, ypos,
-                 xpos+7, ypos+1,
-                 x, nlet_tag, 0, nlet_tag, 0, x, nlet_tag);
-        if (!(old_snd_rcv_flags & IEM_GUI_OLD_RCV_FLAG) &&
-           x->x_gui.x_fsf.x_rcv_able)
-            sys_vgui(".x%lx.c delete %lxVSLDR%si%d\n", canvas, x, nlet_tag, 0);
-    }
-}
-
 static void vslider_draw_select(t_vslider *x, t_glist *glist)
 {
     t_canvas *canvas=glist_getcanvas(glist);
-    //if (glist_isvisible(canvas)) {
-        if(x->x_gui.x_fsf.x_selected)
-        {
-            // check if we are drawing inside a gop abstraction
-            // visible on parent canvas. If so, disable highlighting
-            if (x->x_gui.x_glist == glist_getcanvas(glist))
-            {
-                sys_vgui(".x%lx.c itemconfigure %lxBASE "
-                         "-stroke $pd_colors(selection)\n", canvas, x);
-                sys_vgui(".x%lx.c itemconfigure %lxLABEL "
-                         "-fill $pd_colors(selection)\n", canvas, x);
-                scalehandle_draw_select2(&x->x_gui,glist,"VSLDR",
-                    x->x_gui.x_w-1,x->x_gui.x_h+5-1);
-            }
-            sys_vgui(".x%lx.c addtag selected withtag %lxVSLDR\n", canvas, x);
-        }
-        else
+    if(x->x_gui.x_fsf.x_selected)
+    {
+        // check if we are drawing inside a gop abstraction
+        // visible on parent canvas. If so, disable highlighting
+        if (x->x_gui.x_glist == glist_getcanvas(glist))
         {
-            sys_vgui(".x%lx.c itemconfigure %lxBASE -stroke %s\n",
-                canvas, x, IEM_GUI_COLOR_NORMAL);
-            sys_vgui(".x%lx.c itemconfigure %lxLABEL -fill #%6.6x\n",
-                canvas, x, x->x_gui.x_lcol);
-            sys_vgui(".x%lx.c dtag %lxVSLDR selected\n", canvas, x);
-            scalehandle_draw_erase2(&x->x_gui,glist);
+            sys_vgui(".x%lx.c itemconfigure %lxBASE "
+                     "-stroke $pd_colors(selection)\n", canvas, x);
+            scalehandle_draw_select2(&x->x_gui,glist,"VSLDR",
+                x->x_gui.x_w-1,x->x_gui.x_h+5-1);
         }
-    //}
+    }
+    else
+    {
+        sys_vgui(".x%lx.c itemconfigure %lxBASE -stroke %s\n",
+            canvas, x, IEM_GUI_COLOR_NORMAL);
+        scalehandle_draw_erase2(&x->x_gui,glist);
+    }
+    iemgui_label_draw_select(&x->x_gui,canvas);
+    iemgui_tag_selected(&x->x_gui,canvas,"VSLDR");
 }
 
 void vslider_check_minmax(t_vslider *x, double min, double max);
@@ -351,7 +258,7 @@ void vslider_draw(t_vslider *x, t_glist *glist, int mode)
     else if(mode == IEM_GUI_DRAW_MODE_SELECT)
         vslider_draw_select(x, glist);
     else if(mode == IEM_GUI_DRAW_MODE_ERASE)
-        vslider_draw_erase(x, glist);
+        iemgui_draw_erase(&x->x_gui, glist, "VSLDR");
     else if(mode == IEM_GUI_DRAW_MODE_CONFIG)
         vslider_draw_config(x, glist);
     else if(mode >= IEM_GUI_DRAW_MODE_IO)
@@ -858,14 +765,7 @@ void g_vslider_setup(void)
     class_addmethod(scalehandle_class, (t_method)vslider__motionhook,
             gensym("_motion"), A_FLOAT, A_FLOAT, 0);
 
-    vslider_widgetbehavior.w_getrectfn =    vslider_getrect;
-    vslider_widgetbehavior.w_displacefn =   iemgui_displace;
-    vslider_widgetbehavior.w_selectfn =     iemgui_select;
-    vslider_widgetbehavior.w_activatefn =   NULL;
-    vslider_widgetbehavior.w_deletefn =     iemgui_delete;
-    vslider_widgetbehavior.w_visfn =        iemgui_vis;
-    vslider_widgetbehavior.w_clickfn =      vslider_newclick;
-    vslider_widgetbehavior.w_displacefnwtag = iemgui_displace_withtag;
+    wb_init(&vslider_widgetbehavior,vslider_getrect,vslider_newclick);
     class_setwidget(vslider_class, &vslider_widgetbehavior);
     class_sethelpsymbol(vslider_class, gensym("vslider"));
     class_setsavefn(vslider_class, vslider_save);
diff --git a/pd/src/g_vumeter.c b/pd/src/g_vumeter.c
index da0d0cd1a51511661bfdbf7db363eab4576297d8..5e3fb13042c596622595a110b65199b2ec2fc98c 100644
--- a/pd/src/g_vumeter.c
+++ b/pd/src/g_vumeter.c
@@ -113,8 +113,6 @@ static void vu_draw_new(t_vu *x, t_glist *glist)
     scalehandle_draw_new(x->x_gui. x_handle,canvas);
     scalehandle_draw_new(x->x_gui.x_lhandle,canvas);
 
-    //if (glist_isvisible(canvas)) {
-
         char *nlet_tag = iem_get_tag(glist, (t_iemgui *)x);
 
         sys_vgui(".x%lx.c create prect %d %d %d %d "
@@ -160,13 +158,7 @@ static void vu_draw_new(t_vu *x, t_glist *glist)
                  "-tags {%lxPLED %lxVU %s text iemgui}\n",
             canvas, mid+1, ypos+12,
             mid+1, ypos+12, x->x_led_size, x->x_gui.x_bcol, x, x, nlet_tag);
-        sys_vgui(".x%lx.c create text %d %d -text {%s} -anchor w "
-                 "-font {{%s} -%d %s} -fill #%6.6x "
-                 "-tags {%lxLABEL %lxVU %s text iemgui}\n",
-            canvas, xpos+x->x_gui.x_ldx, ypos+x->x_gui.x_ldy,
-            strcmp(x->x_gui.x_lab->s_name, "empty")?x->x_gui.x_lab->s_name:"",
-            x->x_gui.x_font, x->x_gui.x_fontsize, sys_fontweight,
-            x->x_gui.x_lcol, x, x, nlet_tag);
+        iemgui_label_draw_new(&x->x_gui,canvas,xpos,ypos,nlet_tag,"VU");
         if (!x->x_gui.x_fsf.x_snd_able && canvas == x->x_gui.x_glist)
         {
             sys_vgui(".x%lx.c create prect %d %d %d %d "
@@ -245,9 +237,7 @@ static void vu_draw_move(t_vu *x, t_glist *glist)
         }
         x->x_updaterms = x->x_updatepeak = 1;
         sys_queuegui(x, glist, vu_draw_update);
-        sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",
-                 canvas, x, xpos+x->x_gui.x_ldx,
-                 ypos+x->x_gui.x_ldy);
+        iemgui_label_draw_move(&x->x_gui,canvas,xpos,ypos);
         if(!x->x_gui.x_fsf.x_snd_able && canvas == x->x_gui.x_glist)
         {
             sys_vgui(".x%lx.c coords %lxVU%so%d %d %d %d %d\n",
@@ -276,28 +266,10 @@ static void vu_draw_move(t_vu *x, t_glist *glist)
     }
 }
 
-static void vu_draw_erase(t_vu* x,t_glist* glist)
-{
-    t_canvas *canvas=glist_getcanvas(glist);
-
-    sys_vgui(".x%lx.c delete %lxVU\n", canvas, x);
-    sys_vgui(".x%lx.c dtag all %lxVU\n", canvas, x);
-    scalehandle_draw_erase2(&x->x_gui,glist);
-}
-
 static void vu_draw_config(t_vu* x, t_glist* glist)
 {
     int i;
     t_canvas *canvas=glist_getcanvas(glist);
-
-    /*
-    char color[64];
-    if (x->x_gui.x_fsf.x_selected)
-        sprintf(color, "$pd_colors(selection)");
-    else
-        sprintf(color, "#%6.6x", x->x_gui.x_lcol);
-    */
-
     for(i = 1; i <= IEM_VU_STEPS; i++)
     {
         sys_vgui(".x%lx.c itemconfigure %lxRLED%d -strokewidth %d\n",
@@ -330,30 +302,13 @@ static void vu_draw_config(t_vu* x, t_glist* glist)
                 x->x_gui.x_fontsize, sys_fontweight,
                 x->x_gui.x_lcol);
     }
-    if (x->x_gui.x_fsf.x_selected && x->x_gui.x_glist == canvas)
-        sys_vgui(".x%lx.c itemconfigure %lxLABEL -font {{%s} -%d %s} "
-                 "-fill $pd_colors(selection) -text {%s} \n",
-            canvas, x, x->x_gui.x_font, x->x_gui.x_fontsize, sys_fontweight,
-            strcmp(x->x_gui.x_lab->s_name, "empty")?x->x_gui.x_lab->s_name:"");
-    else
-        sys_vgui(".x%lx.c itemconfigure %lxLABEL -font {{%s} -%d %s} "
-                 "-fill #%6.6x -text {%s} \n",
-            canvas, x, x->x_gui.x_font, x->x_gui.x_fontsize, sys_fontweight,
-            x->x_gui.x_lcol,
-            strcmp(x->x_gui.x_lab->s_name, "empty")?x->x_gui.x_lab->s_name:"");
-
-    sys_vgui(".x%lx.c itemconfigure %lxRCOVER -fill #%6.6x -stroke #%6.6x\n "
-             ".x%lx.c itemconfigure %lxPLED -strokewidth %d\n "
+    iemgui_label_draw_config(&x->x_gui,canvas);
+    sys_vgui(".x%lx.c itemconfigure %lxRCOVER -fill #%6.6x -stroke #%6.6x\n"
+             ".x%lx.c itemconfigure %lxPLED -strokewidth %d\n"
              ".x%lx.c itemconfigure %lxBASE -fill #%6.6x\n",
              canvas, x, x->x_gui.x_bcol, x->x_gui.x_bcol,
              canvas, x, x->x_led_size,
              canvas, x, x->x_gui.x_bcol);
-    /*
-    sys_vgui(".x%lx.c itemconfigure %lxPLED -width %d\n", canvas, x,
-         x->x_led_size);
-    sys_vgui(".x%lx.c itemconfigure %lxBASE -fill #%6.6x\n",
-        canvas, x, x->x_gui.x_bcol);
-    */
 }
 
 static void vu_draw_io(t_vu* x, t_glist* glist, int old_snd_rcv_flags)
@@ -419,57 +374,50 @@ static void vu_draw_select(t_vu* x,t_glist* glist)
 {
     int i;
     t_canvas *canvas=glist_getcanvas(glist);
-    //if (glist_isvisible(canvas)) {
-        if(x->x_gui.x_fsf.x_selected)
-        {
-            // check if we are drawing inside a gop abstraction
-            // visible on parent canvas. If so, disable highlighting
-            if (x->x_gui.x_glist == glist_getcanvas(glist))
-            {
-                sys_vgui(".x%lx.c itemconfigure %lxBASE "
-                         "-stroke $pd_colors(selection)\n", canvas, x);
-                for(i = 1; i <= IEM_VU_STEPS; i++)
-                {
-                    if(((i + 2) & 3) && (x->x_scale))
-                        sys_vgui(".x%lx.c itemconfigure %lxSCALE%d "
-                            "-fill $pd_colors(selection)\n", canvas, x, i);
-                }
-                if(x->x_scale)
-                {
-                    i=IEM_VU_STEPS+1;
-                    sys_vgui(".x%lx.c itemconfigure %lxSCALE%d "
-                             "-fill $pd_colors(selection)\n", canvas, x, i);
-                }
-                sys_vgui(".x%lx.c itemconfigure %lxLABEL "
-                         "-fill $pd_colors(selection)\n", canvas, x);
-                scalehandle_draw_select2(&x->x_gui,glist,"BNG",
-                    x->x_gui.x_w+2-1,x->x_gui.x_h+4-1);
-            }
-
-            sys_vgui(".x%lx.c addtag selected withtag %lxVU\n", canvas, x);
-        }
-        else
+    if(x->x_gui.x_fsf.x_selected)
+    {
+        // check if we are drawing inside a gop abstraction
+        // visible on parent canvas. If so, disable highlighting
+        if (x->x_gui.x_glist == glist_getcanvas(glist))
         {
-            sys_vgui(".x%lx.c dtag %lxVU selected\n", canvas, x);
-            sys_vgui(".x%lx.c itemconfigure %lxBASE -stroke %s\n",
-                canvas, x, IEM_GUI_COLOR_NORMAL);
+            sys_vgui(".x%lx.c itemconfigure %lxBASE "
+                     "-stroke $pd_colors(selection)\n", canvas, x);
             for(i = 1; i <= IEM_VU_STEPS; i++)
             {
                 if(((i + 2) & 3) && (x->x_scale))
-                    sys_vgui(".x%lx.c itemconfigure %lxSCALE%d -fill #%6.6x\n",
-                        canvas, x, i, x->x_gui.x_lcol);
+                    sys_vgui(".x%lx.c itemconfigure %lxSCALE%d "
+                        "-fill $pd_colors(selection)\n", canvas, x, i);
             }
             if(x->x_scale)
             {
-                i = IEM_VU_STEPS + 1;
+                i=IEM_VU_STEPS+1;
+                sys_vgui(".x%lx.c itemconfigure %lxSCALE%d "
+                         "-fill $pd_colors(selection)\n", canvas, x, i);
+            }
+            scalehandle_draw_select2(&x->x_gui,glist,"VU",
+                x->x_gui.x_w+2-1,x->x_gui.x_h+4-1);
+        }
+    }
+    else
+    {
+        sys_vgui(".x%lx.c itemconfigure %lxBASE -stroke %s\n",
+            canvas, x, IEM_GUI_COLOR_NORMAL);
+        for(i = 1; i <= IEM_VU_STEPS; i++)
+        {
+            if(((i + 2) & 3) && (x->x_scale))
                 sys_vgui(".x%lx.c itemconfigure %lxSCALE%d -fill #%6.6x\n",
                     canvas, x, i, x->x_gui.x_lcol);
-            }
-            sys_vgui(".x%lx.c itemconfigure %lxLABEL -fill #%6.6x\n",
-                canvas, x, x->x_gui.x_lcol);
-            scalehandle_draw_erase2(&x->x_gui,glist);
         }
-    //}
+        if(x->x_scale)
+        {
+            i = IEM_VU_STEPS + 1;
+            sys_vgui(".x%lx.c itemconfigure %lxSCALE%d -fill #%6.6x\n",
+                canvas, x, i, x->x_gui.x_lcol);
+        }
+        scalehandle_draw_erase2(&x->x_gui,glist);
+    }
+    iemgui_label_draw_select(&x->x_gui,canvas);
+    iemgui_tag_selected(&x->x_gui,canvas,"VU");
 }
 
 static void vu__clickhook(t_scalehandle *sh, t_floatarg f, t_floatarg xxx,
@@ -548,7 +496,7 @@ void vu_draw(t_vu *x, t_glist *glist, int mode)
     else if(mode == IEM_GUI_DRAW_MODE_SELECT)
         vu_draw_select(x, glist);
     else if(mode == IEM_GUI_DRAW_MODE_ERASE)
-        vu_draw_erase(x, glist);
+        iemgui_draw_erase(&x->x_gui, glist, "VU");
     else if(mode == IEM_GUI_DRAW_MODE_CONFIG)
         vu_draw_config(x, glist);
     else if(mode >= IEM_GUI_DRAW_MODE_IO)
@@ -1028,14 +976,7 @@ void g_vumeter_setup(void)
     class_addmethod(scalehandle_class, (t_method)vu__motionhook,
             gensym("_motion"), A_FLOAT, A_FLOAT, 0);
 
-    vu_widgetbehavior.w_getrectfn =    vu_getrect;
-    vu_widgetbehavior.w_displacefn =   iemgui_displace;
-    vu_widgetbehavior.w_selectfn =     iemgui_select;
-    vu_widgetbehavior.w_activatefn =   NULL;
-    vu_widgetbehavior.w_deletefn =     iemgui_delete;
-    vu_widgetbehavior.w_visfn =        iemgui_vis;
-    vu_widgetbehavior.w_clickfn =      NULL;
-    vu_widgetbehavior.w_displacefnwtag = iemgui_displace_withtag;
+    wb_init(&vu_widgetbehavior,vu_getrect,0);
     class_setwidget(vu_class,&vu_widgetbehavior);
     class_sethelpsymbol(vu_class, gensym("vu"));
     class_setsavefn(vu_class, vu_save);