From 6a613a0ab173055c57cba2a1e43c9b1fd4e548c3 Mon Sep 17 00:00:00 2001
From: Mathieu L Bouchard <matju@artengine.ca>
Date: Tue, 5 Aug 2014 14:23:27 -0400
Subject: [PATCH] 2nd refactor of scalehandle (including some changes to
 structs t_scalehandle, t_iemgui, t_canvas)

---
 pd/src/g_all_guis.c | 52 ++++++++++++++++---------
 pd/src/g_all_guis.h | 28 +++++++-------
 pd/src/g_bang.c     | 92 +++++++++++---------------------------------
 pd/src/g_canvas.c   | 64 +++++++++----------------------
 pd/src/g_canvas.h   | 13 ++-----
 pd/src/g_hdial.c    | 87 ++++++++++--------------------------------
 pd/src/g_hslider.c  | 87 +++++++++++-------------------------------
 pd/src/g_mycanvas.c | 88 ++++++++++--------------------------------
 pd/src/g_numbox.c   | 81 +++++++++------------------------------
 pd/src/g_toggle.c   | 93 +++++++++++----------------------------------
 pd/src/g_vdial.c    | 87 ++++++++++--------------------------------
 pd/src/g_vslider.c  | 89 +++++++++++--------------------------------
 pd/src/g_vumeter.c  | 89 +++++++++++--------------------------------
 13 files changed, 261 insertions(+), 689 deletions(-)

diff --git a/pd/src/g_all_guis.c b/pd/src/g_all_guis.c
index 6630fc6af..ac82a050f 100644
--- a/pd/src/g_all_guis.c
+++ b/pd/src/g_all_guis.c
@@ -923,11 +923,10 @@ const char *nlet_tag, const char *class_tag) {
 
     //printf("scalehandle_draw_select(x%lx,x%lx,%d,%d,\"%s\",\"%s\")\n",h,canvas,px,py,nlet_tag,class_tag);
 
-    if (h->h_scale ? x->scale_vis : x->label_vis)
-        scalehandle_draw_erase(h,canvas);
+    if (h->h_vis) scalehandle_draw_erase(h,canvas);
 
-//    sys_vgui("canvas %s -width %d -height %d -bg $pd_colors(selection) -bd 0 "
-    sys_vgui("canvas %s -width %d -height %d -bg #0080ff -bd 0 "
+    sys_vgui("canvas %s -width %d -height %d -bg $pd_colors(selection) -bd 0 "
+//    sys_vgui("canvas %s -width %d -height %d -bg #0080ff -bd 0 "
         "-cursor %s\n", h->h_pathname, sx, sy, cursor);
     // there was a %lxBNG tag (or similar) in every scalehandle,
     // but it didn't seem to be used —mathieu
@@ -943,27 +942,42 @@ const char *nlet_tag, const char *class_tag) {
         "-window %s -tags {%s}\n", canvas, x->x_obj.te_xpix+px-sx, x->x_obj.te_ypix+py-sy,
         sx, sy, h->h_pathname, tags);
     scalehandle_bind(h);
-    if (h->h_scale) x->scale_vis = 1;
-    else            x->label_vis = 1;
+    h->h_vis = 1;
 }
 
 void scalehandle_draw_erase(t_scalehandle *h, t_glist *canvas) {
         sys_vgui("destroy %s\n", h->h_pathname);
         sys_vgui(".x%lx.c delete %lx%s\n", canvas, h->h_master, h->h_scale ? "SCALE" : "LABELH");
+        h->h_vis = 0;
 }
 
 void scalehandle_draw_erase2(t_iemgui *x, t_glist *canvas) {
-    /*if (x->x_fsf.x_selected)
-    {
-        scalehandle_draw_erase((t_scalehandle *)(x->x_handle),canvas);
-        scalehandle_draw_erase((t_scalehandle *)(x->x_lhandle),canvas);
-    }*/
-    if (x->scale_vis) {
-		scalehandle_draw_erase((t_scalehandle *)(x->x_handle),canvas);
-		x->scale_vis = 0;
-	}
-    if (x->label_vis) {
-		scalehandle_draw_erase((t_scalehandle *)(x->x_lhandle),canvas);
-		x->label_vis = 0;
-	}
+	t_scalehandle *sh = (t_scalehandle *)(x->x_handle);
+	t_scalehandle *lh = (t_scalehandle *)(x->x_lhandle);
+    if (sh->h_vis) scalehandle_draw_erase(sh,canvas);
+    if (lh->h_vis) scalehandle_draw_erase(lh,canvas);
+}
+
+void scalehandle_draw_new(t_scalehandle *h, t_glist *canvas) {
+    sprintf(h->h_pathname, ".x%lx.h%lx", (t_int)canvas, (t_int)h);
+}
+
+t_scalehandle *scalehandle_new(t_class *c, t_iemgui *x, int scale) {
+    t_scalehandle *h = (t_scalehandle *)pd_new(c);
+    char buf[64];
+    h->h_master = (t_gobj*)x;
+    sprintf(buf, "_h%lx", (t_int)h);
+    pd_bind((t_pd *)h, h->h_bindsym = gensym(buf));
+    sprintf(h->h_outlinetag, "h%lx", (t_int)h);
+    h->h_dragon = 0;
+    h->h_scale = scale;
+    h->h_offset_x = 0;
+    h->h_offset_y = 0;
+    h->h_vis = 0;
+    return h;
+}
+
+void scalehandle_free(t_scalehandle *h) {
+    pd_unbind((t_pd *)h, h->h_bindsym);
+    pd_free((t_pd *)h);
 }
diff --git a/pd/src/g_all_guis.h b/pd/src/g_all_guis.h
index 9f077cdbe..62d6cdc5e 100644
--- a/pd/src/g_all_guis.h
+++ b/pd/src/g_all_guis.h
@@ -177,6 +177,9 @@ typedef struct _scalehandle
     int        h_dragon;
     int        h_dragx;
     int        h_dragy;
+    int        h_offset_x;
+    int        h_offset_y;
+    int        h_vis;
 } t_scalehandle;
 
 static t_class *scalehandle_class;
@@ -198,22 +201,16 @@ typedef struct _iemgui
     int                x_fcol;
     int                x_bcol;
     int                x_lcol;
-    t_symbol           *x_snd;              /* send symbol */
-    t_symbol           *x_rcv;              /* receive */
-    t_symbol           *x_lab;              /* label */
-    t_symbol           *x_snd_unexpanded;   /* same 3, with '$' unexpanded */
-    t_symbol           *x_rcv_unexpanded;
-    t_symbol           *x_lab_unexpanded;
+    t_symbol          *x_snd;              /* send symbol */
+    t_symbol          *x_rcv;              /* receive */
+    t_symbol          *x_lab;              /* label */
+    t_symbol          *x_snd_unexpanded;   /* same 3, with '$' unexpanded */
+    t_symbol          *x_rcv_unexpanded;
+    t_symbol          *x_lab_unexpanded;
     int                x_binbufindex;       /* where in binbuf to find these */
     int                x_labelbindex;       /* where in binbuf to find label */
-    t_pd               *x_handle;
-    int                scale_offset_x;
-    int                scale_offset_y;
-    int                scale_vis;
-    t_pd               *x_lhandle;
-    int                label_offset_x;
-    int                label_offset_y;
-    int                label_vis;
+    t_scalehandle     *x_handle;
+    t_scalehandle     *x_lhandle;
     int                x_vis;               /* is the object drawn? */
     int                x_changed;           /* has the value changed so that we need to do graphic update */
 } t_iemgui;
@@ -410,3 +407,6 @@ EXTERN void scalehandle_bind(t_scalehandle *h);
 EXTERN void scalehandle_draw_select(t_scalehandle *h, t_glist *canvas, int px, int py, const char *nlet_tag, const char *class_tag);
 EXTERN void scalehandle_draw_erase(t_scalehandle *h, t_glist *canvas);
 EXTERN void scalehandle_draw_erase2(t_iemgui *x, t_glist *canvas);
+EXTERN void scalehandle_draw_new(t_scalehandle *x, t_glist *canvas);
+EXTERN t_scalehandle *scalehandle_new(t_class *c, t_iemgui *x, int scale);
+EXTERN void scalehandle_free(t_scalehandle *h);
diff --git a/pd/src/g_bang.c b/pd/src/g_bang.c
index 38e1624da..6bfca7fe2 100644
--- a/pd/src/g_bang.c
+++ b/pd/src/g_bang.c
@@ -57,11 +57,8 @@ void bng_draw_new(t_bng *x, t_glist *glist)
     int ypos=text_ypix(&x->x_gui.x_obj, glist);
     t_canvas *canvas=glist_getcanvas(glist);
 
-    t_scalehandle *sh = (t_scalehandle *)x->x_gui.x_handle;
-    sprintf(sh->h_pathname, ".x%lx.h%lx", (t_int)canvas, (t_int)sh);
-
-    t_scalehandle *lh = (t_scalehandle *)x->x_gui.x_lhandle;
-    sprintf(lh->h_pathname, ".x%lx.h%lx", (t_int)canvas, (t_int)lh);
+    scalehandle_draw_new(x->x_gui. x_handle,canvas);
+    scalehandle_draw_new(x->x_gui.x_lhandle,canvas);
 
     //if (glist_isvisible(canvas)) {
 
@@ -278,13 +275,11 @@ static void bng__clickhook(t_scalehandle *sh, t_floatarg f,
 
     if (xxx)
     {
-        x->x_gui.scale_offset_x = xxx;
-        x->x_gui.label_offset_x = xxx;
+        sh->h_offset_x = xxx;
     }
     if (yyy)
     {
-        x->x_gui.scale_offset_y = yyy;
-        x->x_gui.label_offset_y = yyy;
+        sh->h_offset_y = yyy;
     }
 
     int newstate = (int)f;
@@ -301,10 +296,10 @@ static void bng__clickhook(t_scalehandle *sh, t_floatarg f,
                 sh->h_dragx = sh->h_dragy;
             else sh->h_dragy = sh->h_dragx;
 
-            x->x_gui.x_w = x->x_gui.x_w + sh->h_dragx - x->x_gui.scale_offset_x;
+            x->x_gui.x_w = x->x_gui.x_w + sh->h_dragx - sh->h_offset_x;
             if (x->x_gui.x_w < SCALE_BNG_MINWIDTH)
                 x->x_gui.x_w = SCALE_BNG_MINWIDTH;
-            x->x_gui.x_h = x->x_gui.x_h + sh->h_dragy - x->x_gui.scale_offset_y;
+            x->x_gui.x_h = x->x_gui.x_h + sh->h_dragy - sh->h_offset_y;
             if (x->x_gui.x_h < SCALE_BNG_MINHEIGHT)
                 x->x_gui.x_h = SCALE_BNG_MINHEIGHT;
 
@@ -359,9 +354,9 @@ static void bng__clickhook(t_scalehandle *sh, t_floatarg f,
         if (sh->h_dragx || sh->h_dragy)
         {
             x->x_gui.x_ldx = x->x_gui.x_ldx + sh->h_dragx -
-                x->x_gui.label_offset_x;
+                sh->h_offset_x;
             x->x_gui.x_ldy = x->x_gui.x_ldy + sh->h_dragy -
-                x->x_gui.label_offset_y;
+                sh->h_offset_y;
             canvas_dirty(x->x_gui.x_glist, 1);
         }
 
@@ -392,7 +387,7 @@ static void bng__clickhook(t_scalehandle *sh, t_floatarg f,
         if (glist_isvisible(x->x_gui.x_glist))
         {
             sys_vgui("lower %s\n", sh->h_pathname);
-            t_scalehandle *othersh = (t_scalehandle *)x->x_gui.x_handle;
+            t_scalehandle *othersh = x->x_gui.x_handle;
             sys_vgui("lower .x%lx.h%lx\n",
                 (t_int)glist_getcanvas(x->x_gui.x_glist), (t_int)othersh);
         }
@@ -415,18 +410,18 @@ static void bng__motionhook(t_scalehandle *sh,
         if (dx > dy)
         {
             dx = dy;
-            x->x_gui.scale_offset_x = x->x_gui.scale_offset_y;
+            sh->h_offset_x = sh->h_offset_y;
         }
         else
         {
             dy = dx;
-            x->x_gui.scale_offset_y = x->x_gui.scale_offset_x;
+            sh->h_offset_y = sh->h_offset_x;
         }
 
         newx = x->x_gui.x_obj.te_xpix + x->x_gui.x_w -
-            x->x_gui.scale_offset_x + dx;
+            sh->h_offset_x + dx;
         newy = x->x_gui.x_obj.te_ypix + x->x_gui.x_h -
-            x->x_gui.scale_offset_y + dy;
+            sh->h_offset_y + dy;
 
         if (newx < x->x_gui.x_obj.te_xpix + SCALE_BNG_MINWIDTH)
             newx = x->x_gui.x_obj.te_xpix + SCALE_BNG_MINWIDTH;
@@ -446,8 +441,8 @@ static void bng__motionhook(t_scalehandle *sh,
 
         if (properties)
         {
-            int new_w = x->x_gui.x_w - x->x_gui.scale_offset_x + sh->h_dragx;
-            //int new_h = x->x_gui.x_h - x->x_gui.scale_offset_y + sh->h_dragy;
+            int new_w = x->x_gui.x_w - sh->h_offset_x + sh->h_dragx;
+            //int new_h = x->x_gui.x_h - sh->h_offset_y + sh->h_dragy;
             sys_vgui(".gfxstub%lx.dim.w_ent delete 0 end\n", properties);
             sys_vgui(".gfxstub%lx.dim.w_ent insert 0 %d\n", properties, new_w);
             //sys_vgui(".gfxstub%lx.dim.h_ent delete 0 end\n", properties);
@@ -466,8 +461,8 @@ static void bng__motionhook(t_scalehandle *sh,
 
         if (properties)
         {
-            int new_x = x->x_gui.x_ldx - x->x_gui.label_offset_x + sh->h_dragx;
-            int new_y = x->x_gui.x_ldy - x->x_gui.label_offset_y + sh->h_dragy;
+            int new_x = x->x_gui.x_ldx - sh->h_offset_x + sh->h_dragx;
+            int new_y = x->x_gui.x_ldy - sh->h_offset_y + sh->h_dragy;
             sys_vgui(".gfxstub%lx.label.xy.x_entry delete 0 end\n", properties);
             sys_vgui(".gfxstub%lx.label.xy.x_entry insert 0 %d\n", properties,
                 new_x);
@@ -483,8 +478,8 @@ static void bng__motionhook(t_scalehandle *sh,
             t_canvas *canvas=glist_getcanvas(x->x_gui.x_glist);
             sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",
                  canvas, x,
-                 xpos+x->x_gui.x_ldx + sh->h_dragx - x->x_gui.label_offset_x,
-                 ypos+x->x_gui.x_ldy + sh->h_dragy - x->x_gui.label_offset_y);
+                 xpos+x->x_gui.x_ldx + sh->h_dragx - sh->h_offset_x,
+                 ypos+x->x_gui.x_ldy + sh->h_dragy - sh->h_offset_y);
         }
     }
 }
@@ -857,36 +852,8 @@ static void *bng_new(t_symbol *s, int argc, t_atom *argv)
     x->x_clock_lck = clock_new(x, (t_method)bng_tick_lck);
     outlet_new(&x->x_gui.x_obj, &s_bang);
 
-    /* scale handle init */
-    t_scalehandle *sh;
-    char buf[64];
-    x->x_gui.x_handle = pd_new(scalehandle_class);
-    sh = (t_scalehandle *)x->x_gui.x_handle;
-    sh->h_master = (t_gobj*)x;
-    sprintf(buf, "_h%lx", (t_int)sh);
-    pd_bind(x->x_gui.x_handle, sh->h_bindsym = gensym(buf));
-    sprintf(sh->h_outlinetag, "h%lx", (t_int)sh);
-    sh->h_dragon = 0;
-    sh->h_scale = 1;
-    x->x_gui.scale_offset_x = 0;
-    x->x_gui.scale_offset_y = 0;
-    x->x_gui.scale_vis = 0;
-
-    /* label handle init */
-    t_scalehandle *lh;
-    char lhbuf[64];
-    x->x_gui.x_lhandle = pd_new(scalehandle_class);
-    lh = (t_scalehandle *)x->x_gui.x_lhandle;
-    lh->h_master = (t_gobj*)x;
-    sprintf(lhbuf, "_h%lx", (t_int)lh);
-    pd_bind(x->x_gui.x_lhandle, lh->h_bindsym = gensym(lhbuf));
-    sprintf(lh->h_outlinetag, "h%lx", (t_int)lh);
-    lh->h_dragon = 0;
-    lh->h_scale = 0;
-    x->x_gui.label_offset_x = 0;
-    x->x_gui.label_offset_y = 0;
-    x->x_gui.label_vis = 0;
-
+    x->x_gui. x_handle = scalehandle_new(scalehandle_class,(t_iemgui *)x,1);
+    x->x_gui.x_lhandle = scalehandle_new(scalehandle_class,(t_iemgui *)x,0);
     x->x_gui.x_obj.te_iemgui = 1;
     x->x_gui.x_changed = 0;
 
@@ -902,21 +869,8 @@ static void bng_ff(t_bng *x)
     clock_free(x->x_clock_hld);
     gfxstub_deleteforkey(x);
 
-    /* scale handle deconstructor */
-    if (x->x_gui.x_handle)
-    {
-        pd_unbind(x->x_gui.x_handle,
-            ((t_scalehandle *)x->x_gui.x_handle)->h_bindsym);
-        pd_free(x->x_gui.x_handle);
-    }
-
-    /* label handle deconstructor */
-    if (x->x_gui.x_lhandle)
-    {
-        pd_unbind(x->x_gui.x_lhandle,
-            ((t_scalehandle *)x->x_gui.x_lhandle)->h_bindsym);
-        pd_free(x->x_gui.x_lhandle);
-    }
+    if (x->x_gui. x_handle) scalehandle_free(x->x_gui. x_handle);
+    if (x->x_gui.x_lhandle) scalehandle_free(x->x_gui.x_lhandle);
 }
 
 void g_bang_setup(void)
diff --git a/pd/src/g_canvas.c b/pd/src/g_canvas.c
index 98388c7ef..1d7c36a17 100644
--- a/pd/src/g_canvas.c
+++ b/pd/src/g_canvas.c
@@ -438,40 +438,11 @@ t_canvas *canvas_new(void *dummy, t_symbol *sel, int argc, t_atom *argv)
     x->gl_font = sys_nearestfontsize(font);
     pd_pushsym(&x->gl_pd);
 
-    //dpsaha@vt.edu gop resize
-
-    //resize blob
-    t_scalehandle *sh;
-    char buf[64];
-    x->x_handle = pd_new(scalehandle_class);
-    sh = (t_scalehandle *)x->x_handle;
-    sh->h_master = (t_gobj*)x;
-    sprintf(buf, "_h%lx", (t_int)sh);
-    pd_bind(x->x_handle, sh->h_bindsym = gensym(buf));
-    sprintf(sh->h_outlinetag, "h%lx", (t_int)sh);
-    sh->h_dragon = 0;
-    sh->h_scale = 1;
-    x->scale_offset_x = 0;
-    x->scale_offset_y = 0;
-    x->scale_vis = 0;
-    
-    //move blob    
-    t_scalehandle *mh;
-    char mbuf[64];
-    x->x_mhandle = pd_new(scalehandle_class);
-    mh = (t_scalehandle *)x->x_mhandle;
-    mh->h_master = (t_gobj*)x;
-    sprintf(mbuf, "_h%lx", (t_int)mh);
-    pd_bind(x->x_mhandle, mh->h_bindsym = gensym(mbuf));
-    sprintf(mh->h_outlinetag, "h%lx", (t_int)mh);
-    mh->h_dragon = 0;
-    mh->h_scale = 0;
-    x->move_offset_x = 0;
-    x->move_offset_y = 0;
-    x->move_vis = 0;
+    //dpsaha@vt.edu gop resize (refactored by mathieu)
+    x-> x_handle = scalehandle_new(scalehandle_class,(t_iemgui *)x,1);
+    x->x_mhandle = scalehandle_new(scalehandle_class,(t_iemgui *)x,0);
 
     x->u_queue = canvas_undo_init(x);
-
     return(x);
 }
 
@@ -737,7 +708,9 @@ void canvas_draw_gop_resize_hooks(t_canvas* x)
         sprintf(sh->h_pathname, ".x%lx.h%lx", (t_int)x, (t_int)sh);
         sys_vgui("destroy %s\n", sh->h_pathname);    
         sys_vgui(".x%lx.c delete GOP_resblob\n", x);    
-        
+
+        // instead should call scalehandle_draw_select(t_scalehandle *h, t_glist *canvas, int px, int py, const char *nlet_tag, const char *class_tag);
+        // but the tags are different
         sys_vgui("canvas %s -width %d -height %d -bg $pd_colors(selection) "
                  "-bd 0 -cursor bottom_right_corner\n",
             sh->h_pathname, SCALEHANDLE_WIDTH, SCALEHANDLE_HEIGHT);
@@ -764,6 +737,7 @@ void canvas_draw_gop_resize_hooks(t_canvas* x)
             SCALEHANDLE_WIDTH, SCALEHANDLE_HEIGHT,
             mh->h_pathname, x, x);
         scalehandle_bind(mh);
+        // end of part to be replaced by scalehandle_draw_select
     }
     else
     {
@@ -1987,8 +1961,8 @@ void canvasgop__clickhook(t_scalehandle *sh, t_floatarg f, t_floatarg xxx, t_flo
 
     t_canvas *x = (t_canvas *)(sh->h_master);
 
-    if (xxx) x->scale_offset_x = xxx;
-    if (yyy) x->scale_offset_y = yyy;
+    if (xxx) sh->h_offset_x = xxx;
+    if (yyy) sh->h_offset_y = yyy;
 
     int newstate = (int)f;
     if (sh->h_dragon && newstate == 0)
@@ -2003,11 +1977,11 @@ void canvasgop__clickhook(t_scalehandle *sh, t_floatarg f, t_floatarg xxx, t_flo
             if (sh->h_dragx || sh->h_dragy) 
             {
                 x->gl_pixwidth = x->gl_pixwidth + sh->h_dragx -
-                    x->scale_offset_x;
+                    sh->h_offset_x;
                 if (x->gl_pixwidth < SCALE_GOP_MINWIDTH)
                     x->gl_pixwidth = SCALE_GOP_MINWIDTH;
                 x->gl_pixheight = x->gl_pixheight + sh->h_dragy -
-                    x->scale_offset_y;
+                    sh->h_offset_y;
                 if (x->gl_pixheight < SCALE_GOP_MINHEIGHT)
                     x->gl_pixheight = SCALE_GOP_MINHEIGHT;
 
@@ -2063,8 +2037,8 @@ void canvasgop__clickhook(t_scalehandle *sh, t_floatarg f, t_floatarg xxx, t_flo
 
             if (sh->h_dragx || sh->h_dragy) 
             {
-                x->gl_xmargin = x->gl_xmargin + sh->h_dragx - x->scale_offset_x;
-                x->gl_ymargin = x->gl_ymargin + sh->h_dragy - x->scale_offset_y;
+                x->gl_xmargin = x->gl_xmargin + sh->h_dragx - sh->h_offset_x;
+                x->gl_ymargin = x->gl_ymargin + sh->h_dragy - sh->h_offset_y;
                 canvas_dirty(x, 1);
             }
 
@@ -2127,8 +2101,8 @@ void canvasgop__motionhook(t_scalehandle *sh,t_floatarg f1, t_floatarg f2)
     {
         if(sh->h_scale) //enter if resize_gop hook
         {            
-            newx = x->gl_xmargin + x->gl_pixwidth - x->scale_offset_x + dx;
-            newy = x->gl_ymargin + x->gl_pixheight - x->scale_offset_y + dy;
+            newx = x->gl_xmargin + x->gl_pixwidth - sh->h_offset_x + dx;
+            newy = x->gl_ymargin + x->gl_pixheight - sh->h_offset_y + dy;
 
             if (newx < x->gl_xmargin + SCALE_GOP_MINWIDTH)
                 newx = x->gl_xmargin + SCALE_GOP_MINWIDTH;
@@ -2145,8 +2119,8 @@ void canvasgop__motionhook(t_scalehandle *sh,t_floatarg f1, t_floatarg f2)
             int properties = gfxstub_haveproperties((void *)x);
             if (properties)
             {
-                int new_w = x->gl_pixwidth - x->scale_offset_x + sh->h_dragx;
-                int new_h = x->gl_pixheight - x->scale_offset_y + sh->h_dragy;
+                int new_w = x->gl_pixwidth - sh->h_offset_x + sh->h_dragx;
+                int new_h = x->gl_pixheight - sh->h_offset_y + sh->h_dragy;
                 sys_vgui(".gfxstub%lx.xrange.entry3 delete 0 end\n",
                     properties);
                 sys_vgui(".gfxstub%lx.xrange.entry3 insert 0 %d\n",
@@ -2159,8 +2133,8 @@ void canvasgop__motionhook(t_scalehandle *sh,t_floatarg f1, t_floatarg f2)
         }
         else //enter if move_gop hook
         {
-            newx = x->gl_xmargin - x->scale_offset_x + dx;
-            newy = x->gl_ymargin - x->scale_offset_y + dy;
+            newx = x->gl_xmargin - sh->h_offset_x + dx;
+            newy = x->gl_ymargin - sh->h_offset_y + dy;
         
             int properties = gfxstub_haveproperties((void *)x);
             if (properties)
diff --git a/pd/src/g_canvas.h b/pd/src/g_canvas.h
index 8e25fefec..5e575187b 100644
--- a/pd/src/g_canvas.h
+++ b/pd/src/g_canvas.h
@@ -215,16 +215,9 @@ struct _glist
 	//infinite undo goodies (have to stay here rather than the editor to prevent its obliteration when editor is deleted)
 	t_undo_action *u_queue;
 	t_undo_action *u_last;
-	//dpsaha@vt.edu for the gop dynamic resizing
-	t_pd	   		   *x_handle;
-	int 			   scale_offset_x;	
-	int				   scale_offset_y;
-	int				   scale_vis;	
-	//dpsaha@vt.edu for the move handle
-	t_pd			   *x_mhandle;
-	int				   move_offset_x;
-	int				   move_offset_y;
-	int				   move_vis;
+	//dpsaha@vt.edu for the gop dynamic resizing & move handle (refactored by mathieu)
+	struct _scalehandle *x_handle;
+	struct _scalehandle *x_mhandle;
 	t_pd *gl_svg;
 };
 
diff --git a/pd/src/g_hdial.c b/pd/src/g_hdial.c
index 563de7e1e..040f24309 100644
--- a/pd/src/g_hdial.c
+++ b/pd/src/g_hdial.c
@@ -64,10 +64,8 @@ void hradio_draw_new(t_hradio *x, t_glist *glist)
     int xx11b=text_xpix(&x->x_gui.x_obj, glist), xx11=xx11b, xx21=xx11b+s4;
     int xx22=xx11b+dx-s4;
 
-    t_scalehandle *sh = (t_scalehandle *)x->x_gui.x_handle;
-    sprintf(sh->h_pathname, ".x%lx.h%lx", (t_int)canvas, (t_int)sh);
-    t_scalehandle *lh = (t_scalehandle *)x->x_gui.x_lhandle;
-    sprintf(lh->h_pathname, ".x%lx.h%lx", (t_int)canvas, (t_int)lh);
+    scalehandle_draw_new(x->x_gui. x_handle,canvas);
+    scalehandle_draw_new(x->x_gui.x_lhandle,canvas);
 
     //if (glist_isvisible(canvas)) {
 
@@ -299,13 +297,11 @@ static void hradio__clickhook(t_scalehandle *sh, t_floatarg f, t_floatarg xxx,
 
      if (xxx)
      {
-         x->x_gui.scale_offset_x = xxx;
-         x->x_gui.label_offset_x = xxx;
+         sh->h_offset_x = xxx;
      }
      if (yyy)
      {
-         x->x_gui.scale_offset_y = yyy;
-         x->x_gui.label_offset_y = yyy;
+         sh->h_offset_y = yyy;
      }
 
     int newstate = (int)f;
@@ -321,10 +317,10 @@ static void hradio__clickhook(t_scalehandle *sh, t_floatarg f, t_floatarg xxx,
 
             sh->h_dragx = sh->h_dragy;
 
-            x->x_gui.x_w = x->x_gui.x_w + sh->h_dragx - x->x_gui.scale_offset_y;
+            x->x_gui.x_w = x->x_gui.x_w + sh->h_dragx - sh->h_offset_y;
             if (x->x_gui.x_w < SCALE_HRDO_MINWIDTH)
                 x->x_gui.x_w = SCALE_HRDO_MINWIDTH;
-            x->x_gui.x_h = x->x_gui.x_h + sh->h_dragy - x->x_gui.scale_offset_y;
+            x->x_gui.x_h = x->x_gui.x_h + sh->h_dragy - sh->h_offset_y;
             if (x->x_gui.x_h < SCALE_HRDO_MINHEIGHT)
                 x->x_gui.x_h = SCALE_HRDO_MINHEIGHT;
 
@@ -378,9 +374,9 @@ static void hradio__clickhook(t_scalehandle *sh, t_floatarg f, t_floatarg xxx,
         if (sh->h_dragx || sh->h_dragy)
         {
             x->x_gui.x_ldx =
-                x->x_gui.x_ldx + sh->h_dragx - x->x_gui.label_offset_x;
+                x->x_gui.x_ldx + sh->h_dragx - sh->h_offset_x;
             x->x_gui.x_ldy =
-                x->x_gui.x_ldy + sh->h_dragy - x->x_gui.label_offset_y;
+                x->x_gui.x_ldy + sh->h_dragy - sh->h_offset_y;
 
             canvas_dirty(x->x_gui.x_glist, 1);
         }
@@ -412,7 +408,7 @@ static void hradio__clickhook(t_scalehandle *sh, t_floatarg f, t_floatarg xxx,
         if (glist_isvisible(x->x_gui.x_glist))
         {
             sys_vgui("lower %s\n", sh->h_pathname);
-            t_scalehandle *othersh = (t_scalehandle *)x->x_gui.x_handle;
+            t_scalehandle *othersh = x->x_gui.x_handle;
             sys_vgui("lower .x%lx.h%lx\n",
                 (t_int)glist_getcanvas(x->x_gui.x_glist), (t_int)othersh);
         }
@@ -436,9 +432,9 @@ static void hradio__motionhook(t_scalehandle *sh,
         dx = dy;
 
         newx = x->x_gui.x_obj.te_xpix + x->x_gui.x_w*x->x_number +
-            (dx - x->x_gui.scale_offset_y) * x->x_number;
+            (dx - sh->h_offset_y) * x->x_number;
         newy = x->x_gui.x_obj.te_ypix + x->x_gui.x_h +
-            (dy - x->x_gui.scale_offset_y);
+            (dy - sh->h_offset_y);
 
         if (newx < x->x_gui.x_obj.te_xpix + SCALE_HRDO_MINWIDTH*x->x_number)
             newx = x->x_gui.x_obj.te_xpix + SCALE_HRDO_MINWIDTH*x->x_number;
@@ -458,8 +454,8 @@ static void hradio__motionhook(t_scalehandle *sh,
 
         if (properties)
         {
-            int new_w = x->x_gui.x_w - x->x_gui.scale_offset_x + sh->h_dragx;
-            //int new_h = x->x_gui.x_h - x->x_gui.scale_offset_y + sh->h_dragy;
+            int new_w = x->x_gui.x_w - sh->h_offset_x + sh->h_dragx;
+            //int new_h = x->x_gui.x_h - sh->h_offset_y + sh->h_dragy;
             sys_vgui(".gfxstub%lx.dim.w_ent delete 0 end\n", properties);
             sys_vgui(".gfxstub%lx.dim.w_ent insert 0 %d\n", properties, new_w);
             //sys_vgui(".gfxstub%lx.dim.h_ent delete 0 end\n", properties);
@@ -478,8 +474,8 @@ static void hradio__motionhook(t_scalehandle *sh,
 
         if (properties)
         {
-            int new_x = x->x_gui.x_ldx - x->x_gui.label_offset_x + sh->h_dragx;
-            int new_y = x->x_gui.x_ldy - x->x_gui.label_offset_y + sh->h_dragy;
+            int new_x = x->x_gui.x_ldx - sh->h_offset_x + sh->h_dragx;
+            int new_y = x->x_gui.x_ldy - sh->h_offset_y + sh->h_dragy;
             sys_vgui(".gfxstub%lx.label.xy.x_entry delete 0 end\n", properties);
             sys_vgui(".gfxstub%lx.label.xy.x_entry insert 0 %d\n",
                 properties, new_x);
@@ -495,8 +491,8 @@ static void hradio__motionhook(t_scalehandle *sh,
             t_canvas *canvas=glist_getcanvas(x->x_gui.x_glist);
             sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",
                  canvas, x,
-                 xpos+x->x_gui.x_ldx + sh->h_dragx - x->x_gui.label_offset_x,
-                 ypos+x->x_gui.x_ldy + sh->h_dragy - x->x_gui.label_offset_y);
+                 xpos+x->x_gui.x_ldx + sh->h_dragx - sh->h_offset_x,
+                 ypos+x->x_gui.x_ldy + sh->h_dragy - sh->h_offset_y);
         }
     }
 }
@@ -947,36 +943,8 @@ static void *hradio_donew(t_symbol *s, int argc, t_atom *argv, int old)
     iemgui_all_colfromload(&x->x_gui, bflcol);
     outlet_new(&x->x_gui.x_obj, &s_list);
 
-    /* scale handle init */
-    t_scalehandle *sh;
-    char buf[64];
-    x->x_gui.x_handle = pd_new(scalehandle_class);
-    sh = (t_scalehandle *)x->x_gui.x_handle;
-    sh->h_master = (t_gobj*)x;
-    sprintf(buf, "_h%lx", (t_int)sh);
-    pd_bind(x->x_gui.x_handle, sh->h_bindsym = gensym(buf));
-    sprintf(sh->h_outlinetag, "h%lx", (t_int)sh);
-    sh->h_dragon = 0;
-    sh->h_scale = 1;
-    x->x_gui.scale_offset_x = 0;
-    x->x_gui.scale_offset_y = 0;
-    x->x_gui.scale_vis = 0;
-
-    /* label handle init */
-    t_scalehandle *lh;
-    char lhbuf[64];
-    x->x_gui.x_lhandle = pd_new(scalehandle_class);
-    lh = (t_scalehandle *)x->x_gui.x_lhandle;
-    lh->h_master = (t_gobj*)x;
-    sprintf(lhbuf, "_h%lx", (t_int)lh);
-    pd_bind(x->x_gui.x_lhandle, lh->h_bindsym = gensym(lhbuf));
-    sprintf(lh->h_outlinetag, "h%lx", (t_int)lh);
-    lh->h_dragon = 0;
-    lh->h_scale = 0;
-    x->x_gui.label_offset_x = 0;
-    x->x_gui.label_offset_y = 0;
-    x->x_gui.label_vis = 0;
-
+    x->x_gui. x_handle = scalehandle_new(scalehandle_class,(t_iemgui *)x,1);
+    x->x_gui.x_lhandle = scalehandle_new(scalehandle_class,(t_iemgui *)x,0);
     x->x_gui.x_obj.te_iemgui = 1;
 
     return (x);
@@ -998,21 +966,8 @@ static void hradio_ff(t_hradio *x)
         pd_unbind(&x->x_gui.x_obj.ob_pd, x->x_gui.x_rcv);
     gfxstub_deleteforkey(x);
 
-    /* scale handle deconstructor */
-    if (x->x_gui.x_handle)
-    {
-        pd_unbind(x->x_gui.x_handle,
-            ((t_scalehandle *)x->x_gui.x_handle)->h_bindsym);
-        pd_free(x->x_gui.x_handle);
-    }
-
-    /* label handle deconstructor */
-    if (x->x_gui.x_lhandle)
-    {
-        pd_unbind(x->x_gui.x_lhandle,
-            ((t_scalehandle *)x->x_gui.x_lhandle)->h_bindsym);
-        pd_free(x->x_gui.x_lhandle);
-    }
+    if (x->x_gui. x_handle) scalehandle_free(x->x_gui. x_handle);
+    if (x->x_gui.x_lhandle) scalehandle_free(x->x_gui.x_lhandle);
 }
 
 void g_hradio_setup(void)
diff --git a/pd/src/g_hslider.c b/pd/src/g_hslider.c
index d9721616d..3be9a04d2 100644
--- a/pd/src/g_hslider.c
+++ b/pd/src/g_hslider.c
@@ -77,10 +77,8 @@ static void hslider_draw_new(t_hslider *x, t_glist *glist)
     int r = xpos + 3 + (x->x_val + 50)/100;
     t_canvas *canvas=glist_getcanvas(glist);
 
-    t_scalehandle *sh = (t_scalehandle *)x->x_gui.x_handle;
-    sprintf(sh->h_pathname, ".x%lx.h%lx", (t_int)canvas, (t_int)sh);
-    t_scalehandle *lh = (t_scalehandle *)x->x_gui.x_lhandle;
-    sprintf(lh->h_pathname, ".x%lx.h%lx", (t_int)canvas, (t_int)lh);
+    scalehandle_draw_new(x->x_gui. x_handle,canvas);
+    scalehandle_draw_new(x->x_gui.x_lhandle,canvas);
 
     //if (glist_isvisible(canvas)) {
 
@@ -283,13 +281,11 @@ static void hslider__clickhook(t_scalehandle *sh, t_floatarg f,
 
      if (xxx)
      {
-         x->x_gui.scale_offset_x = xxx;
-         x->x_gui.label_offset_x = xxx;
+         sh->h_offset_x = xxx;
      }
      if (yyy)
      {
-         x->x_gui.scale_offset_y = yyy;
-         x->x_gui.label_offset_y = yyy;
+         sh->h_offset_y = yyy;
      }
 
     int newstate = (int)f;
@@ -304,13 +300,13 @@ static void hslider__clickhook(t_scalehandle *sh, t_floatarg f,
         {
 
             double width_change_ratio = (double)(x->x_gui.x_w +
-                sh->h_dragx - x->x_gui.scale_offset_x)/(double)x->x_gui.x_w;
+                sh->h_dragx - sh->h_offset_x)/(double)x->x_gui.x_w;
             x->x_val = x->x_val * width_change_ratio;
 
-            x->x_gui.x_w = x->x_gui.x_w + sh->h_dragx - x->x_gui.scale_offset_x;
+            x->x_gui.x_w = x->x_gui.x_w + sh->h_dragx - sh->h_offset_x;
             if (x->x_gui.x_w < SCALE_HSLD_MINWIDTH)
                 x->x_gui.x_w = SCALE_HSLD_MINWIDTH;
-            x->x_gui.x_h = x->x_gui.x_h + sh->h_dragy - x->x_gui.scale_offset_y;
+            x->x_gui.x_h = x->x_gui.x_h + sh->h_dragy - sh->h_offset_y;
             if (x->x_gui.x_h < SCALE_HSLD_MINHEIGHT)
                 x->x_gui.x_h = SCALE_HSLD_MINHEIGHT;
 
@@ -369,9 +365,9 @@ static void hslider__clickhook(t_scalehandle *sh, t_floatarg f,
         {
 
             x->x_gui.x_ldx = x->x_gui.x_ldx +
-                sh->h_dragx - x->x_gui.label_offset_x;
+                sh->h_dragx - sh->h_offset_x;
             x->x_gui.x_ldy = x->x_gui.x_ldy +
-                sh->h_dragy - x->x_gui.label_offset_y;
+                sh->h_dragy - sh->h_offset_y;
 
             canvas_dirty(x->x_gui.x_glist, 1);
         }
@@ -403,7 +399,7 @@ static void hslider__clickhook(t_scalehandle *sh, t_floatarg f,
         if (glist_isvisible(x->x_gui.x_glist))
         {
             sys_vgui("lower %s\n", sh->h_pathname);
-            t_scalehandle *othersh = (t_scalehandle *)x->x_gui.x_handle;
+            t_scalehandle *othersh = x->x_gui.x_handle;
             sys_vgui("lower .x%lx.h%lx\n",
                 (t_int)glist_getcanvas(x->x_gui.x_glist), (t_int)othersh);
         }
@@ -423,9 +419,9 @@ static void hslider__motionhook(t_scalehandle *sh,
         int dx = (int)f1, dy = (int)f2;
         int newx, newy;
         newx = x->x_gui.x_obj.te_xpix +
-            x->x_gui.x_w - x->x_gui.scale_offset_x + dx;
+            x->x_gui.x_w - sh->h_offset_x + dx;
         newy = x->x_gui.x_obj.te_ypix +
-            x->x_gui.x_h - x->x_gui.scale_offset_y + dy;
+            x->x_gui.x_h - sh->h_offset_y + dy;
 
         if (newx < x->x_gui.x_obj.te_xpix + SCALE_HSLD_MINWIDTH)
             newx = x->x_gui.x_obj.te_xpix + SCALE_HSLD_MINWIDTH;
@@ -445,8 +441,8 @@ static void hslider__motionhook(t_scalehandle *sh,
 
         if (properties)
         {
-            int new_w = x->x_gui.x_w - x->x_gui.scale_offset_x + sh->h_dragx;
-            int new_h = x->x_gui.x_h - x->x_gui.scale_offset_y + sh->h_dragy;
+            int new_w = x->x_gui.x_w - sh->h_offset_x + sh->h_dragx;
+            int new_h = x->x_gui.x_h - sh->h_offset_y + sh->h_dragy;
             sys_vgui(".gfxstub%lx.dim.w_ent delete 0 end\n", properties);
             sys_vgui(".gfxstub%lx.dim.w_ent insert 0 %d\n", properties, new_w);
             sys_vgui(".gfxstub%lx.dim.h_ent delete 0 end\n", properties);
@@ -464,8 +460,8 @@ static void hslider__motionhook(t_scalehandle *sh,
 
         if (properties)
         {
-            int new_x = x->x_gui.x_ldx - x->x_gui.label_offset_x + sh->h_dragx;
-            int new_y = x->x_gui.x_ldy - x->x_gui.label_offset_y + sh->h_dragy;
+            int new_x = x->x_gui.x_ldx - sh->h_offset_x + sh->h_dragx;
+            int new_y = x->x_gui.x_ldy - sh->h_offset_y + sh->h_dragy;
             sys_vgui(".gfxstub%lx.label.xy.x_entry delete 0 end\n", properties);
             sys_vgui(".gfxstub%lx.label.xy.x_entry insert 0 %d\n",
                 properties, new_x);
@@ -481,8 +477,8 @@ static void hslider__motionhook(t_scalehandle *sh,
             t_canvas *canvas=glist_getcanvas(x->x_gui.x_glist);
             sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",
                  canvas, x,
-                 xpos+x->x_gui.x_ldx + sh->h_dragx - x->x_gui.label_offset_x,
-                 ypos+x->x_gui.x_ldy + sh->h_dragy - x->x_gui.label_offset_y);
+                 xpos+x->x_gui.x_ldx + sh->h_dragx - sh->h_offset_x,
+                 ypos+x->x_gui.x_ldy + sh->h_dragy - sh->h_offset_y);
         }
     }
 }
@@ -962,36 +958,8 @@ static void *hslider_new(t_symbol *s, int argc, t_atom *argv)
     iemgui_verify_snd_ne_rcv(&x->x_gui);
     outlet_new(&x->x_gui.x_obj, &s_float);
 
-    /* scale handle init */
-    t_scalehandle *sh;
-    char buf[64];
-    x->x_gui.x_handle = pd_new(scalehandle_class);
-    sh = (t_scalehandle *)x->x_gui.x_handle;
-    sh->h_master = (t_gobj*)x;
-    sprintf(buf, "_h%lx", (t_int)sh);
-    pd_bind(x->x_gui.x_handle, sh->h_bindsym = gensym(buf));
-    sprintf(sh->h_outlinetag, "h%lx", (t_int)sh);
-    sh->h_dragon = 0;
-    sh->h_scale = 1;
-    x->x_gui.scale_offset_x = 0;
-    x->x_gui.scale_offset_y = 0;
-    x->x_gui.scale_vis = 0;
-
-    /* label handle init */
-    t_scalehandle *lh;
-    char lhbuf[64];
-    x->x_gui.x_lhandle = pd_new(scalehandle_class);
-    lh = (t_scalehandle *)x->x_gui.x_lhandle;
-    lh->h_master = (t_gobj*)x;
-    sprintf(lhbuf, "_h%lx", (t_int)lh);
-    pd_bind(x->x_gui.x_lhandle, lh->h_bindsym = gensym(lhbuf));
-    sprintf(lh->h_outlinetag, "h%lx", (t_int)lh);
-    lh->h_dragon = 0;
-    lh->h_scale = 0;
-    x->x_gui.label_offset_x = 0;
-    x->x_gui.label_offset_y = 0;
-    x->x_gui.label_vis = 0;
-
+    x->x_gui. x_handle = scalehandle_new(scalehandle_class,(t_iemgui *)x,1);
+    x->x_gui.x_lhandle = scalehandle_new(scalehandle_class,(t_iemgui *)x,0);
     x->x_gui.x_obj.te_iemgui = 1;
     x->x_gui.x_changed = 0;
 
@@ -1004,19 +972,8 @@ static void hslider_free(t_hslider *x)
         pd_unbind(&x->x_gui.x_obj.ob_pd, x->x_gui.x_rcv);
     gfxstub_deleteforkey(x);
 
-    /* scale handle deconstructor */
-    if (x->x_gui.x_handle)
-    {
-        pd_unbind(x->x_gui.x_handle, ((t_scalehandle *)x->x_gui.x_handle)->h_bindsym);
-        pd_free(x->x_gui.x_handle);
-    }
-
-    /* label handle deconstructor */
-    if (x->x_gui.x_lhandle)
-    {
-        pd_unbind(x->x_gui.x_lhandle, ((t_scalehandle *)x->x_gui.x_lhandle)->h_bindsym);
-        pd_free(x->x_gui.x_lhandle);
-    }
+    if (x->x_gui. x_handle) scalehandle_free(x->x_gui. x_handle);
+    if (x->x_gui.x_lhandle) scalehandle_free(x->x_gui.x_lhandle);
 }
 
 void g_hslider_setup(void)
diff --git a/pd/src/g_mycanvas.c b/pd/src/g_mycanvas.c
index 6563489cd..924667ce5 100644
--- a/pd/src/g_mycanvas.c
+++ b/pd/src/g_mycanvas.c
@@ -41,11 +41,8 @@ void my_canvas_draw_new(t_my_canvas *x, t_glist *glist)
     int ypos=text_ypix(&x->x_gui.x_obj, glist);
     t_canvas *canvas=glist_getcanvas(glist);
 
-    t_scalehandle *sh = (t_scalehandle *)x->x_gui.x_handle;
-    sprintf(sh->h_pathname, ".x%lx.h%lx", (t_int)canvas, (t_int)sh);
-
-    t_scalehandle *lh = (t_scalehandle *)x->x_gui.x_lhandle;
-    sprintf(lh->h_pathname, ".x%lx.h%lx", (t_int)canvas, (t_int)lh);
+    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);
@@ -181,13 +178,11 @@ static void my_canvas__clickhook(t_scalehandle *sh, t_floatarg f,
 
     if (xxx)
     {
-        x->x_gui.scale_offset_x = xxx;
-        x->x_gui.label_offset_x = xxx;
+        sh->h_offset_x = xxx;
     }
     if (yyy)
     {
-        x->x_gui.scale_offset_y = yyy;
-        x->x_gui.label_offset_y = yyy;
+        sh->h_offset_y = yyy;
     }
 
     int newstate = (int)f;
@@ -201,10 +196,10 @@ static void my_canvas__clickhook(t_scalehandle *sh, t_floatarg f,
         if (sh->h_dragx || sh->h_dragy)
         {
 
-            x->x_vis_w = x->x_vis_w + sh->h_dragx - x->x_gui.scale_offset_x;
+            x->x_vis_w = x->x_vis_w + sh->h_dragx - sh->h_offset_x;
             if (x->x_vis_w < SCALE_CNV_MINWIDTH)
                 x->x_vis_w = SCALE_CNV_MINWIDTH;
-            x->x_vis_h = x->x_vis_h + sh->h_dragy - x->x_gui.scale_offset_y;
+            x->x_vis_h = x->x_vis_h + sh->h_dragy - sh->h_offset_y;
             if (x->x_vis_h < SCALE_CNV_MINHEIGHT)
                 x->x_vis_h = SCALE_CNV_MINHEIGHT;
 
@@ -265,9 +260,9 @@ static void my_canvas__clickhook(t_scalehandle *sh, t_floatarg f,
         {
 
             x->x_gui.x_ldx = x->x_gui.x_ldx + sh->h_dragx -
-                x->x_gui.label_offset_x;
+                sh->h_offset_x;
             x->x_gui.x_ldy = x->x_gui.x_ldy + sh->h_dragy -
-                x->x_gui.label_offset_y;
+                sh->h_offset_y;
 
             canvas_dirty(x->x_gui.x_glist, 1);
         }
@@ -298,7 +293,7 @@ static void my_canvas__clickhook(t_scalehandle *sh, t_floatarg f,
         if (glist_isvisible(x->x_gui.x_glist))
         {
             sys_vgui("lower %s\n", sh->h_pathname);
-            t_scalehandle *othersh = (t_scalehandle *)x->x_gui.x_handle;
+            t_scalehandle *othersh = x->x_gui.x_handle;
             sys_vgui("lower .x%lx.h%lx\n",
                 (t_int)glist_getcanvas(x->x_gui.x_glist), (t_int)othersh);
         }
@@ -318,9 +313,9 @@ static void my_canvas__motionhook(t_scalehandle *sh,
         int dx = (int)f1, dy = (int)f2;
         int newx, newy;
         newx = x->x_gui.x_obj.te_xpix + x->x_vis_w -
-            x->x_gui.scale_offset_x + dx;
+            sh->h_offset_x + dx;
         newy = x->x_gui.x_obj.te_ypix + x->x_vis_h -
-            x->x_gui.scale_offset_y + dy;
+            sh->h_offset_y + dy;
 
         if (newx < x->x_gui.x_obj.te_xpix + SCALE_CNV_MINWIDTH)
             newx = x->x_gui.x_obj.te_xpix + SCALE_CNV_MINWIDTH;
@@ -340,8 +335,8 @@ static void my_canvas__motionhook(t_scalehandle *sh,
 
         if (properties)
         {
-            int new_w = x->x_vis_w - x->x_gui.scale_offset_x + sh->h_dragx;
-            int new_h = x->x_vis_h - x->x_gui.scale_offset_y + sh->h_dragy;
+            int new_w = x->x_vis_w - sh->h_offset_x + sh->h_dragx;
+            int new_h = x->x_vis_h - sh->h_offset_y + sh->h_dragy;
             sys_vgui(".gfxstub%lx.rng.min_ent delete 0 end\n", properties);
             sys_vgui(".gfxstub%lx.rng.min_ent insert 0 %d\n", properties, new_w);
             sys_vgui(".gfxstub%lx.rng.max_ent delete 0 end\n", properties);
@@ -365,8 +360,8 @@ static void my_canvas__motionhook(t_scalehandle *sh,
 
         if (properties)
         {
-            int new_x = x->x_gui.x_ldx - x->x_gui.label_offset_x + sh->h_dragx;
-            int new_y = x->x_gui.x_ldy - x->x_gui.label_offset_y + sh->h_dragy;
+            int new_x = x->x_gui.x_ldx - sh->h_offset_x + sh->h_dragx;
+            int new_y = x->x_gui.x_ldy - sh->h_offset_y + sh->h_dragy;
             sys_vgui(".gfxstub%lx.label.xy.x_entry delete 0 end\n", properties);
             sys_vgui(".gfxstub%lx.label.xy.x_entry insert 0 %d\n", properties, new_x);
             sys_vgui(".gfxstub%lx.label.xy.y_entry delete 0 end\n", properties);
@@ -380,8 +375,8 @@ static void my_canvas__motionhook(t_scalehandle *sh,
             t_canvas *canvas=glist_getcanvas(x->x_gui.x_glist);
             sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",
                 canvas, x,
-                xpos+x->x_gui.x_ldx + sh->h_dragx - x->x_gui.label_offset_x,
-                ypos+x->x_gui.x_ldy + sh->h_dragy - x->x_gui.label_offset_y);
+                xpos+x->x_gui.x_ldx + sh->h_dragx - sh->h_offset_x,
+                ypos+x->x_gui.x_ldy + sh->h_dragy - sh->h_offset_y);
         }
     }
 }
@@ -660,36 +655,8 @@ static void *my_canvas_new(t_symbol *s, int argc, t_atom *argv)
     x->x_at[1].a_type = A_FLOAT;
     iemgui_verify_snd_ne_rcv(&x->x_gui);
 
-    /* scale handle init */
-    t_scalehandle *sh;
-    char buf[64];
-    x->x_gui.x_handle = pd_new(scalehandle_class);
-    sh = (t_scalehandle *)x->x_gui.x_handle;
-    sh->h_master = (t_gobj*)x;
-    sprintf(buf, "_h%lx", (t_int)sh);
-    pd_bind(x->x_gui.x_handle, sh->h_bindsym = gensym(buf));
-    sprintf(sh->h_outlinetag, "h%lx", (t_int)sh);
-    sh->h_dragon = 0;
-    sh->h_scale = 1;
-    x->x_gui.scale_offset_x = 0;
-    x->x_gui.scale_offset_y = 0;
-    x->x_gui.scale_vis = 0;
-
-    /* label handle init */
-    t_scalehandle *lh;
-    char lhbuf[64];
-    x->x_gui.x_lhandle = pd_new(scalehandle_class);
-    lh = (t_scalehandle *)x->x_gui.x_lhandle;
-    lh->h_master = (t_gobj*)x;
-    sprintf(lhbuf, "_h%lx", (t_int)lh);
-    pd_bind(x->x_gui.x_lhandle, lh->h_bindsym = gensym(lhbuf));
-    sprintf(lh->h_outlinetag, "h%lx", (t_int)lh);
-    lh->h_dragon = 0;
-    lh->h_scale = 0;
-    x->x_gui.label_offset_x = 0;
-    x->x_gui.label_offset_y = 0;
-    x->x_gui.label_vis = 0;
-
+    x->x_gui. x_handle = scalehandle_new(scalehandle_class,(t_iemgui *)x,1);
+    x->x_gui.x_lhandle = scalehandle_new(scalehandle_class,(t_iemgui *)x,0);
     x->x_gui.x_obj.te_iemgui = 1;
 
     return (x);
@@ -701,21 +668,8 @@ static void my_canvas_ff(t_my_canvas *x)
         pd_unbind(&x->x_gui.x_obj.ob_pd, x->x_gui.x_rcv);
     gfxstub_deleteforkey(x);
 
-    /* scale handle deconstructor */
-    if (x->x_gui.x_handle)
-    {
-        pd_unbind(x->x_gui.x_handle,
-            ((t_scalehandle *)x->x_gui.x_handle)->h_bindsym);
-        pd_free(x->x_gui.x_handle);
-    }
-
-    /* label handle deconstructor */
-    if (x->x_gui.x_lhandle)
-    {
-        pd_unbind(x->x_gui.x_lhandle,
-            ((t_scalehandle *)x->x_gui.x_lhandle)->h_bindsym);
-        pd_free(x->x_gui.x_lhandle);
-    }
+    if (x->x_gui. x_handle) scalehandle_free(x->x_gui. x_handle);
+    if (x->x_gui.x_lhandle) scalehandle_free(x->x_gui.x_lhandle);
 }
 
 void g_mycanvas_setup(void)
diff --git a/pd/src/g_numbox.c b/pd/src/g_numbox.c
index 9e449fd0d..6c32b8438 100644
--- a/pd/src/g_numbox.c
+++ b/pd/src/g_numbox.c
@@ -197,11 +197,8 @@ static void my_numbox_draw_new(t_my_numbox *x, t_glist *glist)
     int ypos=text_ypix(&x->x_gui.x_obj, glist);
     t_canvas *canvas=glist_getcanvas(glist);
 
-    t_scalehandle *sh = (t_scalehandle *)x->x_gui.x_handle;
-    sprintf(sh->h_pathname, ".x%lx.h%lx", (t_int)canvas, (t_int)sh);
-
-    t_scalehandle *lh = (t_scalehandle *)x->x_gui.x_lhandle;
-    sprintf(lh->h_pathname, ".x%lx.h%lx", (t_int)canvas, (t_int)lh);
+    scalehandle_draw_new(x->x_gui. x_handle,canvas);
+    scalehandle_draw_new(x->x_gui.x_lhandle,canvas);
 
     //if (glist_isvisible(canvas)) {
 
@@ -516,13 +513,11 @@ static void my_numbox__clickhook(t_scalehandle *sh, t_floatarg f,
 
      if (xxx)
      {
-         x->x_gui.scale_offset_x = xxx;
-         x->x_gui.label_offset_x = xxx;
+         sh->h_offset_x = xxx;
      }
      if (yyy)
      {
-         x->x_gui.scale_offset_y = yyy;
-         x->x_gui.label_offset_y = yyy;
+         sh->h_offset_y = yyy;
      }
 
     int newstate = (int)f;
@@ -603,9 +598,9 @@ static void my_numbox__clickhook(t_scalehandle *sh, t_floatarg f,
         {
 
             x->x_gui.x_ldx =
-                x->x_gui.x_ldx + sh->h_dragx - x->x_gui.label_offset_x;
+                x->x_gui.x_ldx + sh->h_dragx - sh->h_offset_x;
             x->x_gui.x_ldy =
-                x->x_gui.x_ldy + sh->h_dragy - x->x_gui.label_offset_y;
+                x->x_gui.x_ldy + sh->h_dragy - sh->h_offset_y;
 
             canvas_dirty(x->x_gui.x_glist, 1);
         }
@@ -637,7 +632,7 @@ static void my_numbox__clickhook(t_scalehandle *sh, t_floatarg f,
         if (glist_isvisible(x->x_gui.x_glist))
         {
             sys_vgui("lower %s\n", sh->h_pathname);
-            t_scalehandle *othersh = (t_scalehandle *)x->x_gui.x_handle;
+            t_scalehandle *othersh = x->x_gui.x_handle;
             sys_vgui("lower .x%lx.h%lx\n",
                 (t_int)glist_getcanvas(x->x_gui.x_glist), (t_int)othersh);
         }
@@ -659,7 +654,7 @@ static void my_numbox__motionhook(t_scalehandle *sh,
 
         /* first calculate y */
         newy = x->x_gui.x_obj.te_ypix + x->x_gui.x_h +
-            (dy - x->x_gui.scale_offset_y);
+            (dy - sh->h_offset_y);
         if (newy < x->x_gui.x_obj.te_ypix + SCALE_NUM_MINHEIGHT)
             newy = x->x_gui.x_obj.te_ypix + SCALE_NUM_MINHEIGHT;
 
@@ -677,7 +672,7 @@ static void my_numbox__motionhook(t_scalehandle *sh,
         char_w /= 36;
 
         /* get the new total width */
-        int new_total_width = x->x_numwidth + (dx - x->x_gui.scale_offset_x);
+        int new_total_width = x->x_numwidth + (dx - sh->h_offset_x);
         
         /* now figure out what does this translate into in terms of
            character length */
@@ -727,8 +722,8 @@ static void my_numbox__motionhook(t_scalehandle *sh,
 
         if (properties)
         {
-            int new_x = x->x_gui.x_ldx - x->x_gui.label_offset_x + sh->h_dragx;
-            int new_y = x->x_gui.x_ldy - x->x_gui.label_offset_y + sh->h_dragy;
+            int new_x = x->x_gui.x_ldx - sh->h_offset_x + sh->h_dragx;
+            int new_y = x->x_gui.x_ldy - sh->h_offset_y + sh->h_dragy;
             sys_vgui(".gfxstub%lx.label.xy.x_entry delete 0 end\n", properties);
             sys_vgui(".gfxstub%lx.label.xy.x_entry insert 0 %d\n",
                 properties, new_x);
@@ -744,8 +739,8 @@ static void my_numbox__motionhook(t_scalehandle *sh,
             t_canvas *canvas=glist_getcanvas(x->x_gui.x_glist);
             sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",
                  canvas, x,
-                 xpos+x->x_gui.x_ldx + sh->h_dragx - x->x_gui.label_offset_x,
-                 ypos+x->x_gui.x_ldy + sh->h_dragy - x->x_gui.label_offset_y);
+                 xpos+x->x_gui.x_ldx + sh->h_dragx - sh->h_offset_x,
+                 ypos+x->x_gui.x_ldy + sh->h_dragy - sh->h_offset_y);
         }
     }
 }
@@ -1311,40 +1306,11 @@ static void *my_numbox_new(t_symbol *s, int argc, t_atom *argv)
     x->x_gui.x_fsf.x_change = 0;
     outlet_new(&x->x_gui.x_obj, &s_float);
 
-    /* scale handle init */
-    t_scalehandle *sh;
-    char buf[64];
-    x->x_gui.x_handle = pd_new(scalehandle_class);
-    sh = (t_scalehandle *)x->x_gui.x_handle;
-    sh->h_master = (t_gobj*)x;
-    sprintf(buf, "_h%lx", (t_int)sh);
-    pd_bind(x->x_gui.x_handle, sh->h_bindsym = gensym(buf));
-    sprintf(sh->h_outlinetag, "h%lx", (t_int)sh);
-    sh->h_dragon = 0;
-    sh->h_scale = 1;
-    x->x_gui.scale_offset_x = 0;
-    x->x_gui.scale_offset_y = 0;
-    x->x_gui.scale_vis = 0;
-
-    /* label handle init */
-    t_scalehandle *lh;
-    char lhbuf[64];
-    x->x_gui.x_lhandle = pd_new(scalehandle_class);
-    lh = (t_scalehandle *)x->x_gui.x_lhandle;
-    lh->h_master = (t_gobj*)x;
-    sprintf(lhbuf, "_h%lx", (t_int)lh);
-    pd_bind(x->x_gui.x_lhandle, lh->h_bindsym = gensym(lhbuf));
-    sprintf(lh->h_outlinetag, "h%lx", (t_int)lh);
-    lh->h_dragon = 0;
-    lh->h_scale = 0;
-    x->x_gui.label_offset_x = 0;
-    x->x_gui.label_offset_y = 0;
-    x->x_gui.label_vis = 0;
-    
+    x->x_gui. x_handle = scalehandle_new(scalehandle_class,(t_iemgui *)x,1);
+    x->x_gui.x_lhandle = scalehandle_new(scalehandle_class,(t_iemgui *)x,0);
     x->x_scalewidth = 0;
     x->x_scaleheight = 0;
     x->x_tmpfontsize = 0;
-
     x->x_gui.x_obj.te_iemgui = 1;
     x->x_gui.x_changed = 0;
 
@@ -1359,21 +1325,8 @@ static void my_numbox_free(t_my_numbox *x)
     clock_free(x->x_clock_wait);
     gfxstub_deleteforkey(x);
 
-    /* scale handle deconstructor */
-    if (x->x_gui.x_handle)
-    {
-        pd_unbind(x->x_gui.x_handle,
-            ((t_scalehandle *)x->x_gui.x_handle)->h_bindsym);
-        pd_free(x->x_gui.x_handle);
-    }
-
-    /* label handle deconstructor */
-    if (x->x_gui.x_lhandle)
-    {
-        pd_unbind(x->x_gui.x_lhandle,
-            ((t_scalehandle *)x->x_gui.x_lhandle)->h_bindsym);
-        pd_free(x->x_gui.x_lhandle);
-    }
+    if (x->x_gui. x_handle) scalehandle_free(x->x_gui. x_handle);
+    if (x->x_gui.x_lhandle) scalehandle_free(x->x_gui.x_lhandle);
 }
 
 void g_numbox_setup(void)
diff --git a/pd/src/g_toggle.c b/pd/src/g_toggle.c
index 65fba1541..bbce2998f 100644
--- a/pd/src/g_toggle.c
+++ b/pd/src/g_toggle.c
@@ -60,11 +60,8 @@ void toggle_draw_new(t_toggle *x, t_glist *glist)
     int w=1, xx=text_xpix(&x->x_gui.x_obj, glist),
         yy=text_ypix(&x->x_gui.x_obj, glist);
 
-    t_scalehandle *sh = (t_scalehandle *)x->x_gui.x_handle;
-    sprintf(sh->h_pathname, ".x%lx.h%lx", (t_int)canvas, (t_int)sh);
-
-    t_scalehandle *lh = (t_scalehandle *)x->x_gui.x_lhandle;
-    sprintf(lh->h_pathname, ".x%lx.h%lx", (t_int)canvas, (t_int)lh);
+    scalehandle_draw_new(x->x_gui. x_handle,canvas);
+    scalehandle_draw_new(x->x_gui.x_lhandle,canvas);
 
     //if (glist_isvisible(canvas)) {
 
@@ -300,13 +297,11 @@ static void toggle__clickhook(t_scalehandle *sh, t_floatarg f,
 
     if (xxx)
     {
-        x->x_gui.scale_offset_x = xxx;
-        x->x_gui.label_offset_x = xxx;
+        sh->h_offset_x = xxx;
     }
     if (yyy)
     {
-        x->x_gui.scale_offset_y = yyy;
-        x->x_gui.label_offset_y = yyy;
+        sh->h_offset_y = yyy;
     }
 
     int newstate = (int)f;
@@ -324,10 +319,10 @@ static void toggle__clickhook(t_scalehandle *sh, t_floatarg f,
                 sh->h_dragx = sh->h_dragy;
             else sh->h_dragy = sh->h_dragx;
 
-            x->x_gui.x_w = x->x_gui.x_w + sh->h_dragx - x->x_gui.scale_offset_x;
+            x->x_gui.x_w = x->x_gui.x_w + sh->h_dragx - sh->h_offset_x;
             if (x->x_gui.x_w < SCALE_TGL_MINWIDTH)
                 x->x_gui.x_w = SCALE_TGL_MINWIDTH;
-            x->x_gui.x_h = x->x_gui.x_h + sh->h_dragy - x->x_gui.scale_offset_y;
+            x->x_gui.x_h = x->x_gui.x_h + sh->h_dragy - sh->h_offset_y;
             if (x->x_gui.x_h < SCALE_TGL_MINHEIGHT)
                 x->x_gui.x_h = SCALE_TGL_MINHEIGHT;
 
@@ -383,9 +378,9 @@ static void toggle__clickhook(t_scalehandle *sh, t_floatarg f,
         {
 
             x->x_gui.x_ldx =
-                x->x_gui.x_ldx + sh->h_dragx - x->x_gui.label_offset_x;
+                x->x_gui.x_ldx + sh->h_dragx - sh->h_offset_x;
             x->x_gui.x_ldy =
-                x->x_gui.x_ldy + sh->h_dragy - x->x_gui.label_offset_y;
+                x->x_gui.x_ldy + sh->h_dragy - sh->h_offset_y;
 
             canvas_dirty(x->x_gui.x_glist, 1);
         }
@@ -417,7 +412,7 @@ static void toggle__clickhook(t_scalehandle *sh, t_floatarg f,
         if (glist_isvisible(x->x_gui.x_glist))
         {
             sys_vgui("lower %s\n", sh->h_pathname);
-            t_scalehandle *othersh = (t_scalehandle *)x->x_gui.x_handle;
+            t_scalehandle *othersh = x->x_gui.x_handle;
             sys_vgui("lower .x%lx.h%lx\n",
                 (t_int)glist_getcanvas(x->x_gui.x_glist), (t_int)othersh);
         }
@@ -440,18 +435,18 @@ static void toggle__motionhook(t_scalehandle *sh, t_floatarg f1, t_floatarg f2)
         if (dx > dy)
         {
             dx = dy;
-            x->x_gui.scale_offset_x = x->x_gui.scale_offset_y;
+            sh->h_offset_x = sh->h_offset_y;
         }
         else
         {
             dy = dx;
-            x->x_gui.scale_offset_y = x->x_gui.scale_offset_x;
+            sh->h_offset_y = sh->h_offset_x;
         }
 
         newx = x->x_gui.x_obj.te_xpix + x->x_gui.x_w -
-            x->x_gui.scale_offset_x + dx;
+            sh->h_offset_x + dx;
         newy = x->x_gui.x_obj.te_ypix + x->x_gui.x_h -
-            x->x_gui.scale_offset_y + dy;
+            sh->h_offset_y + dy;
 
         if (newx < x->x_gui.x_obj.te_xpix + SCALE_TGL_MINWIDTH)
             newx = x->x_gui.x_obj.te_xpix + SCALE_TGL_MINWIDTH;
@@ -471,8 +466,8 @@ static void toggle__motionhook(t_scalehandle *sh, t_floatarg f1, t_floatarg f2)
 
         if (properties)
         {
-            int new_w = x->x_gui.x_w - x->x_gui.scale_offset_x + sh->h_dragx;
-            //int new_h = x->x_gui.x_h - x->x_gui.scale_offset_y + sh->h_dragy;
+            int new_w = x->x_gui.x_w - sh->h_offset_x + sh->h_dragx;
+            //int new_h = x->x_gui.x_h - sh->h_offset_y + sh->h_dragy;
             sys_vgui(".gfxstub%lx.dim.w_ent delete 0 end\n", properties);
             sys_vgui(".gfxstub%lx.dim.w_ent insert 0 %d\n", properties, new_w);
             //sys_vgui(".gfxstub%lx.dim.h_ent delete 0 end\n", properties);
@@ -490,8 +485,8 @@ static void toggle__motionhook(t_scalehandle *sh, t_floatarg f1, t_floatarg f2)
 
         if (properties)
         {
-            int new_x = x->x_gui.x_ldx - x->x_gui.label_offset_x + sh->h_dragx;
-            int new_y = x->x_gui.x_ldy - x->x_gui.label_offset_y + sh->h_dragy;
+            int new_x = x->x_gui.x_ldx - sh->h_offset_x + sh->h_dragx;
+            int new_y = x->x_gui.x_ldy - sh->h_offset_y + sh->h_dragy;
             sys_vgui(".gfxstub%lx.label.xy.x_entry delete 0 end\n", properties);
             sys_vgui(".gfxstub%lx.label.xy.x_entry insert 0 %d\n", properties,
                 new_x);
@@ -507,8 +502,8 @@ static void toggle__motionhook(t_scalehandle *sh, t_floatarg f1, t_floatarg f2)
             t_canvas *canvas=glist_getcanvas(x->x_gui.x_glist);
             sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",
                 canvas, x,
-                xpos+x->x_gui.x_ldx + sh->h_dragx - x->x_gui.label_offset_x,
-                ypos+x->x_gui.x_ldy + sh->h_dragy - x->x_gui.label_offset_y);
+                xpos+x->x_gui.x_ldx + sh->h_dragx - sh->h_offset_x,
+                ypos+x->x_gui.x_ldy + sh->h_dragy - sh->h_offset_y);
         }
     }
 }
@@ -802,38 +797,9 @@ static void *toggle_new(t_symbol *s, int argc, t_atom *argv)
     iemgui_verify_snd_ne_rcv(&x->x_gui);
     outlet_new(&x->x_gui.x_obj, &s_float);
 
-    /* scale handle init */
-    t_scalehandle *sh;
-    char buf[64];
-    x->x_gui.x_handle = pd_new(scalehandle_class);
-    sh = (t_scalehandle *)x->x_gui.x_handle;
-    sh->h_master = (t_gobj*)x;
-    sprintf(buf, "_h%lx", (t_int)sh);
-    pd_bind(x->x_gui.x_handle, sh->h_bindsym = gensym(buf));
-    sprintf(sh->h_outlinetag, "h%lx", (t_int)sh);
-    sh->h_dragon = 0;
-    sh->h_scale = 1;
-    x->x_gui.scale_offset_x = 0;
-    x->x_gui.scale_offset_y = 0;
-    x->x_gui.scale_vis = 0;
-
-    /* label handle init */
-    t_scalehandle *lh;
-    char lhbuf[64];
-    x->x_gui.x_lhandle = pd_new(scalehandle_class);
-    lh = (t_scalehandle *)x->x_gui.x_lhandle;
-    lh->h_master = (t_gobj*)x;
-    sprintf(lhbuf, "_h%lx", (t_int)lh);
-    pd_bind(x->x_gui.x_lhandle, lh->h_bindsym = gensym(lhbuf));
-    sprintf(lh->h_outlinetag, "h%lx", (t_int)lh);
-    lh->h_dragon = 0;
-    lh->h_scale = 0;
-    x->x_gui.label_offset_x = 0;
-    x->x_gui.label_offset_y = 0;
-    x->x_gui.label_vis = 0;
-
+    x->x_gui. x_handle = scalehandle_new(scalehandle_class,(t_iemgui *)x,1);
+    x->x_gui.x_lhandle = scalehandle_new(scalehandle_class,(t_iemgui *)x,0);
     x->x_gui.x_obj.te_iemgui = 1;
-
     x->x_gui.x_changed = 1;
 
     return (x);
@@ -845,21 +811,8 @@ static void toggle_ff(t_toggle *x)
         pd_unbind(&x->x_gui.x_obj.ob_pd, x->x_gui.x_rcv);
     gfxstub_deleteforkey(x);
 
-    /* scale handle deconstructor */
-    if (x->x_gui.x_handle)
-    {
-        pd_unbind(x->x_gui.x_handle,
-            ((t_scalehandle *)x->x_gui.x_handle)->h_bindsym);
-        pd_free(x->x_gui.x_handle);
-    }
-
-    /* label handle deconstructor */
-    if (x->x_gui.x_lhandle)
-    {
-        pd_unbind(x->x_gui.x_lhandle,
-            ((t_scalehandle *)x->x_gui.x_lhandle)->h_bindsym);
-        pd_free(x->x_gui.x_lhandle);
-    }
+    if (x->x_gui. x_handle) scalehandle_free(x->x_gui. x_handle);
+    if (x->x_gui.x_lhandle) scalehandle_free(x->x_gui.x_lhandle);
 }
 
 void g_toggle_setup(void)
diff --git a/pd/src/g_vdial.c b/pd/src/g_vdial.c
index ccdafd511..8366b573a 100644
--- a/pd/src/g_vdial.c
+++ b/pd/src/g_vdial.c
@@ -62,10 +62,8 @@ void vradio_draw_new(t_vradio *x, t_glist *glist)
     int xx11=text_xpix(&x->x_gui.x_obj, glist), xx12=xx11+dy;
     int xx21=xx11+s4, xx22=xx12-s4;
 
-    t_scalehandle *sh = (t_scalehandle *)x->x_gui.x_handle;
-    sprintf(sh->h_pathname, ".x%lx.h%lx", (t_int)canvas, (t_int)sh);
-    t_scalehandle *lh = (t_scalehandle *)x->x_gui.x_lhandle;
-    sprintf(lh->h_pathname, ".x%lx.h%lx", (t_int)canvas, (t_int)lh);
+    scalehandle_draw_new(x->x_gui. x_handle,canvas);
+    scalehandle_draw_new(x->x_gui.x_lhandle,canvas);
 
     //if (glist_isvisible(canvas)) {
 
@@ -302,13 +300,11 @@ static void vradio__clickhook(t_scalehandle *sh, t_floatarg f, t_floatarg xxx,
 
     if (xxx)
     {
-        x->x_gui.scale_offset_x = xxx;
-        x->x_gui.label_offset_x = xxx;
+        sh->h_offset_x = xxx;
     }
     if (yyy)
     {
-        x->x_gui.scale_offset_y = yyy;
-        x->x_gui.label_offset_y = yyy;
+        sh->h_offset_y = yyy;
     }
 
     int newstate = (int)f;
@@ -324,10 +320,10 @@ static void vradio__clickhook(t_scalehandle *sh, t_floatarg f, t_floatarg xxx,
 
             sh->h_dragy = sh->h_dragx;
 
-            x->x_gui.x_w = x->x_gui.x_w + sh->h_dragx - x->x_gui.scale_offset_x;
+            x->x_gui.x_w = x->x_gui.x_w + sh->h_dragx - sh->h_offset_x;
             if (x->x_gui.x_w < SCALE_VRDO_MINWIDTH)
                 x->x_gui.x_w = SCALE_VRDO_MINWIDTH;
-            x->x_gui.x_h = x->x_gui.x_h + sh->h_dragy - x->x_gui.scale_offset_x;
+            x->x_gui.x_h = x->x_gui.x_h + sh->h_dragy - sh->h_offset_x;
             if (x->x_gui.x_h < SCALE_VRDO_MINHEIGHT)
                 x->x_gui.x_h = SCALE_VRDO_MINHEIGHT;
 
@@ -385,9 +381,9 @@ static void vradio__clickhook(t_scalehandle *sh, t_floatarg f, t_floatarg xxx,
         {
 
             x->x_gui.x_ldx =
-                x->x_gui.x_ldx + sh->h_dragx - x->x_gui.label_offset_x;
+                x->x_gui.x_ldx + sh->h_dragx - sh->h_offset_x;
             x->x_gui.x_ldy =
-                x->x_gui.x_ldy + sh->h_dragy - x->x_gui.label_offset_y;
+                x->x_gui.x_ldy + sh->h_dragy - sh->h_offset_y;
 
             canvas_dirty(x->x_gui.x_glist, 1);
         }
@@ -419,7 +415,7 @@ static void vradio__clickhook(t_scalehandle *sh, t_floatarg f, t_floatarg xxx,
         if (glist_isvisible(x->x_gui.x_glist))
         {
             sys_vgui("lower %s\n", sh->h_pathname);
-            t_scalehandle *othersh = (t_scalehandle *)x->x_gui.x_handle;
+            t_scalehandle *othersh = x->x_gui.x_handle;
             sys_vgui("lower .x%lx.h%lx\n",
                 (t_int)glist_getcanvas(x->x_gui.x_glist), (t_int)othersh);
         }
@@ -443,9 +439,9 @@ static void vradio__motionhook(t_scalehandle *sh,
         dy = dx;
 
         newx = x->x_gui.x_obj.te_xpix + x->x_gui.x_h +
-            (dx - x->x_gui.scale_offset_x);
+            (dx - sh->h_offset_x);
         newy = x->x_gui.x_obj.te_ypix + x->x_gui.x_h * x->x_number +
-            (dy - x->x_gui.scale_offset_x) * x->x_number;
+            (dy - sh->h_offset_x) * x->x_number;
 
         if (newx < x->x_gui.x_obj.te_xpix + SCALE_VRDO_MINWIDTH)
             newx = x->x_gui.x_obj.te_xpix + SCALE_VRDO_MINWIDTH;
@@ -465,8 +461,8 @@ static void vradio__motionhook(t_scalehandle *sh,
 
         if (properties)
         {
-            int new_w = x->x_gui.x_h - x->x_gui.scale_offset_y + sh->h_dragy;
-            //int new_h = x->x_gui.x_h - x->x_gui.scale_offset_y + sh->h_dragy;
+            int new_w = x->x_gui.x_h - sh->h_offset_y + sh->h_dragy;
+            //int new_h = x->x_gui.x_h - sh->h_offset_y + sh->h_dragy;
             sys_vgui(".gfxstub%lx.dim.w_ent delete 0 end\n", properties);
             sys_vgui(".gfxstub%lx.dim.w_ent insert 0 %d\n", properties, new_w);
             //sys_vgui(".gfxstub%lx.dim.h_ent delete 0 end\n", properties);
@@ -484,8 +480,8 @@ static void vradio__motionhook(t_scalehandle *sh,
 
         if (properties)
         {
-            int new_x = x->x_gui.x_ldx - x->x_gui.label_offset_x + sh->h_dragx;
-            int new_y = x->x_gui.x_ldy - x->x_gui.label_offset_y + sh->h_dragy;
+            int new_x = x->x_gui.x_ldx - sh->h_offset_x + sh->h_dragx;
+            int new_y = x->x_gui.x_ldy - sh->h_offset_y + sh->h_dragy;
             sys_vgui(".gfxstub%lx.label.xy.x_entry delete 0 end\n", properties);
             sys_vgui(".gfxstub%lx.label.xy.x_entry insert 0 %d\n",
                 properties, new_x);
@@ -501,8 +497,8 @@ static void vradio__motionhook(t_scalehandle *sh,
             t_canvas *canvas=glist_getcanvas(x->x_gui.x_glist);
             sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",
                  canvas, x,
-                 xpos+x->x_gui.x_ldx + sh->h_dragx - x->x_gui.label_offset_x,
-                 ypos+x->x_gui.x_ldy + sh->h_dragy - x->x_gui.label_offset_y);
+                 xpos+x->x_gui.x_ldx + sh->h_dragx - sh->h_offset_x,
+                 ypos+x->x_gui.x_ldy + sh->h_dragy - sh->h_offset_y);
         }
     }
 }
@@ -946,36 +942,8 @@ static void *vradio_donew(t_symbol *s, int argc, t_atom *argv, int old)
     iemgui_all_colfromload(&x->x_gui, bflcol);
     outlet_new(&x->x_gui.x_obj, &s_list);
 
-    /* scale handle init */
-    t_scalehandle *sh;
-    char buf[64];
-    x->x_gui.x_handle = pd_new(scalehandle_class);
-    sh = (t_scalehandle *)x->x_gui.x_handle;
-    sh->h_master = (t_gobj*)x;
-    sprintf(buf, "_h%lx", (t_int)sh);
-    pd_bind(x->x_gui.x_handle, sh->h_bindsym = gensym(buf));
-    sprintf(sh->h_outlinetag, "h%lx", (t_int)sh);
-    sh->h_dragon = 0;
-    sh->h_scale = 1;
-    x->x_gui.scale_offset_x = 0;
-    x->x_gui.scale_offset_y = 0;
-    x->x_gui.scale_vis = 0;
-
-    /* label handle init */
-    t_scalehandle *lh;
-    char lhbuf[64];
-    x->x_gui.x_lhandle = pd_new(scalehandle_class);
-    lh = (t_scalehandle *)x->x_gui.x_lhandle;
-    lh->h_master = (t_gobj*)x;
-    sprintf(lhbuf, "_h%lx", (t_int)lh);
-    pd_bind(x->x_gui.x_lhandle, lh->h_bindsym = gensym(lhbuf));
-    sprintf(lh->h_outlinetag, "h%lx", (t_int)lh);
-    lh->h_dragon = 0;
-    lh->h_scale = 0;
-    x->x_gui.label_offset_x = 0;
-    x->x_gui.label_offset_y = 0;
-    x->x_gui.label_vis = 0;
-
+    x->x_gui. x_handle = scalehandle_new(scalehandle_class,(t_iemgui *)x,1);
+    x->x_gui.x_lhandle = scalehandle_new(scalehandle_class,(t_iemgui *)x,0);
     x->x_gui.x_obj.te_iemgui = 1;
 
     return (x);
@@ -997,21 +965,8 @@ static void vradio_ff(t_vradio *x)
         pd_unbind(&x->x_gui.x_obj.ob_pd, x->x_gui.x_rcv);
     gfxstub_deleteforkey(x);
 
-    /* scale handle deconstructor */
-    if (x->x_gui.x_handle)
-    {
-        pd_unbind(x->x_gui.x_handle,
-            ((t_scalehandle *)x->x_gui.x_handle)->h_bindsym);
-        pd_free(x->x_gui.x_handle);
-    }
-
-    /* label handle deconstructor */
-    if (x->x_gui.x_lhandle)
-    {
-        pd_unbind(x->x_gui.x_lhandle,
-            ((t_scalehandle *)x->x_gui.x_lhandle)->h_bindsym);
-        pd_free(x->x_gui.x_lhandle);
-    }
+    if (x->x_gui. x_handle) scalehandle_free(x->x_gui. x_handle);
+    if (x->x_gui.x_lhandle) scalehandle_free(x->x_gui.x_lhandle);
 }
 
 void g_vradio_setup(void)
diff --git a/pd/src/g_vslider.c b/pd/src/g_vslider.c
index c9cd40c21..524d3731d 100644
--- a/pd/src/g_vslider.c
+++ b/pd/src/g_vslider.c
@@ -79,10 +79,8 @@ static void vslider_draw_new(t_vslider *x, t_glist *glist)
     int r = ypos + 2 + x->x_gui.x_h - (x->x_val + 50)/100;
     t_canvas *canvas=glist_getcanvas(glist);
 
-    t_scalehandle *sh = (t_scalehandle *)x->x_gui.x_handle;
-    sprintf(sh->h_pathname, ".x%lx.h%lx", (t_int)canvas, (t_int)sh);
-    t_scalehandle *lh = (t_scalehandle *)x->x_gui.x_lhandle;
-    sprintf(lh->h_pathname, ".x%lx.h%lx", (t_int)canvas, (t_int)lh);
+    scalehandle_draw_new(x->x_gui. x_handle,canvas);
+    scalehandle_draw_new(x->x_gui.x_lhandle,canvas);
 
     //if (glist_isvisible(canvas)) {
 
@@ -298,13 +296,11 @@ static void vslider__clickhook(t_scalehandle *sh, t_floatarg f, t_floatarg xxx,
 
      if (xxx)
      {
-         x->x_gui.scale_offset_x = xxx;
-         x->x_gui.label_offset_x = xxx;
+         sh->h_offset_x = xxx;
      }
      if (yyy)
      {
-         x->x_gui.scale_offset_y = yyy;
-         x->x_gui.label_offset_y = yyy;
+         sh->h_offset_y = yyy;
      }
 
     int newstate = (int)f;
@@ -319,13 +315,13 @@ static void vslider__clickhook(t_scalehandle *sh, t_floatarg f, t_floatarg xxx,
         {
 
             double height_change_ratio = (double)(x->x_gui.x_h + sh->h_dragy -
-                x->x_gui.scale_offset_y)/(double)x->x_gui.x_h;
+                sh->h_offset_y)/(double)x->x_gui.x_h;
             x->x_val = x->x_val * height_change_ratio;
 
-            x->x_gui.x_w = x->x_gui.x_w + sh->h_dragx - x->x_gui.scale_offset_x;
+            x->x_gui.x_w = x->x_gui.x_w + sh->h_dragx - sh->h_offset_x;
             if (x->x_gui.x_w < SCALE_VSLD_MINWIDTH)
                 x->x_gui.x_w = SCALE_VSLD_MINWIDTH;
-            x->x_gui.x_h = x->x_gui.x_h + sh->h_dragy - x->x_gui.scale_offset_y;
+            x->x_gui.x_h = x->x_gui.x_h + sh->h_dragy - sh->h_offset_y;
             if (x->x_gui.x_h < SCALE_VSLD_MINHEIGHT)
                 x->x_gui.x_h = SCALE_VSLD_MINHEIGHT;
 
@@ -384,9 +380,9 @@ static void vslider__clickhook(t_scalehandle *sh, t_floatarg f, t_floatarg xxx,
         {
 
             x->x_gui.x_ldx = x->x_gui.x_ldx +
-                sh->h_dragx - x->x_gui.label_offset_x;
+                sh->h_dragx - sh->h_offset_x;
             x->x_gui.x_ldy = x->x_gui.x_ldy +
-                sh->h_dragy - x->x_gui.label_offset_y;
+                sh->h_dragy - sh->h_offset_y;
 
             canvas_dirty(x->x_gui.x_glist, 1);
         }
@@ -417,7 +413,7 @@ static void vslider__clickhook(t_scalehandle *sh, t_floatarg f, t_floatarg xxx,
         if (glist_isvisible(x->x_gui.x_glist))
         {
             sys_vgui("lower %s\n", sh->h_pathname);
-            t_scalehandle *othersh = (t_scalehandle *)x->x_gui.x_handle;
+            t_scalehandle *othersh = x->x_gui.x_handle;
             sys_vgui("lower .x%lx.h%lx\n",
                 (t_int)glist_getcanvas(x->x_gui.x_glist), (t_int)othersh);
         }
@@ -438,9 +434,9 @@ static void vslider__motionhook(t_scalehandle *sh,
         int dx = (int)f1, dy = (int)f2;
         int newx, newy;
         newx = x->x_gui.x_obj.te_xpix + x->x_gui.x_w -
-            x->x_gui.scale_offset_x + dx;
+            sh->h_offset_x + dx;
         newy = x->x_gui.x_obj.te_ypix + x->x_gui.x_h -
-            x->x_gui.scale_offset_y + dy;
+            sh->h_offset_y + dy;
 
         if (newx < x->x_gui.x_obj.te_xpix + SCALE_VSLD_MINWIDTH)
             newx = x->x_gui.x_obj.te_xpix + SCALE_VSLD_MINWIDTH;
@@ -460,8 +456,8 @@ static void vslider__motionhook(t_scalehandle *sh,
 
         if (properties)
         {
-            int new_w = x->x_gui.x_w - x->x_gui.scale_offset_x + sh->h_dragx;
-            int new_h = x->x_gui.x_h - x->x_gui.scale_offset_y + sh->h_dragy;
+            int new_w = x->x_gui.x_w - sh->h_offset_x + sh->h_dragx;
+            int new_h = x->x_gui.x_h - sh->h_offset_y + sh->h_dragy;
             sys_vgui(".gfxstub%lx.dim.w_ent delete 0 end\n", properties);
             sys_vgui(".gfxstub%lx.dim.w_ent insert 0 %d\n", properties, new_w);
             sys_vgui(".gfxstub%lx.dim.h_ent delete 0 end\n", properties);
@@ -479,8 +475,8 @@ static void vslider__motionhook(t_scalehandle *sh,
 
         if (properties)
         {
-            int new_x = x->x_gui.x_ldx - x->x_gui.label_offset_x + sh->h_dragx;
-            int new_y = x->x_gui.x_ldy - x->x_gui.label_offset_y + sh->h_dragy;
+            int new_x = x->x_gui.x_ldx - sh->h_offset_x + sh->h_dragx;
+            int new_y = x->x_gui.x_ldy - sh->h_offset_y + sh->h_dragy;
             sys_vgui(".gfxstub%lx.label.xy.x_entry delete 0 end\n", properties);
             sys_vgui(".gfxstub%lx.label.xy.x_entry insert 0 %d\n",
                 properties, new_x);
@@ -496,8 +492,8 @@ static void vslider__motionhook(t_scalehandle *sh,
             t_canvas *canvas=glist_getcanvas(x->x_gui.x_glist);
             sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",
                  canvas, x,
-                 xpos+x->x_gui.x_ldx + sh->h_dragx - x->x_gui.label_offset_x,
-                 ypos+x->x_gui.x_ldy + sh->h_dragy - x->x_gui.label_offset_y);
+                 xpos+x->x_gui.x_ldx + sh->h_dragx - sh->h_offset_x,
+                 ypos+x->x_gui.x_ldy + sh->h_dragy - sh->h_offset_y);
         }
     }
 }
@@ -956,36 +952,8 @@ static void *vslider_new(t_symbol *s, int argc, t_atom *argv)
     iemgui_verify_snd_ne_rcv(&x->x_gui);
     outlet_new(&x->x_gui.x_obj, &s_float);
 
-    /* scale handle init */
-    t_scalehandle *sh;
-    char buf[64];
-    x->x_gui.x_handle = pd_new(scalehandle_class);
-    sh = (t_scalehandle *)x->x_gui.x_handle;
-    sh->h_master = (t_gobj*)x;
-    sprintf(buf, "_h%lx", (t_int)sh);
-    pd_bind(x->x_gui.x_handle, sh->h_bindsym = gensym(buf));
-    sprintf(sh->h_outlinetag, "h%lx", (t_int)sh);
-    sh->h_dragon = 0;
-    sh->h_scale = 1;
-    x->x_gui.scale_offset_x = 0;
-    x->x_gui.scale_offset_y = 0;
-    x->x_gui.scale_vis = 0;
-
-    /* label handle init */
-    t_scalehandle *lh;
-    char lhbuf[64];
-    x->x_gui.x_lhandle = pd_new(scalehandle_class);
-    lh = (t_scalehandle *)x->x_gui.x_lhandle;
-    lh->h_master = (t_gobj*)x;
-    sprintf(lhbuf, "_h%lx", (t_int)lh);
-    pd_bind(x->x_gui.x_lhandle, lh->h_bindsym = gensym(lhbuf));
-    sprintf(lh->h_outlinetag, "h%lx", (t_int)lh);
-    lh->h_dragon = 0;
-    lh->h_scale = 0;
-    x->x_gui.label_offset_x = 0;
-    x->x_gui.label_offset_y = 0;
-    x->x_gui.label_vis = 0;
-
+    x->x_gui. x_handle = scalehandle_new(scalehandle_class,(t_iemgui *)x,1);
+    x->x_gui.x_lhandle = scalehandle_new(scalehandle_class,(t_iemgui *)x,0);
     x->x_gui.x_obj.te_iemgui = 1;
     x->x_gui.x_changed = 0;
 
@@ -998,21 +966,8 @@ static void vslider_free(t_vslider *x)
         pd_unbind(&x->x_gui.x_obj.ob_pd, x->x_gui.x_rcv);
     gfxstub_deleteforkey(x);
 
-    /* scale handle deconstructor */
-    if (x->x_gui.x_handle)
-    {
-        pd_unbind(x->x_gui.x_handle,
-            ((t_scalehandle *)x->x_gui.x_handle)->h_bindsym);
-        pd_free(x->x_gui.x_handle);
-    }
-
-    /* label handle deconstructor */
-    if (x->x_gui.x_lhandle)
-    {
-        pd_unbind(x->x_gui.x_lhandle,
-            ((t_scalehandle *)x->x_gui.x_lhandle)->h_bindsym);
-        pd_free(x->x_gui.x_lhandle);
-    }
+    if (x->x_gui. x_handle) scalehandle_free(x->x_gui. x_handle);
+    if (x->x_gui.x_lhandle) scalehandle_free(x->x_gui.x_lhandle);
 }
 
 void g_vslider_setup(void)
diff --git a/pd/src/g_vumeter.c b/pd/src/g_vumeter.c
index dbafcf5d0..d5e31edd4 100644
--- a/pd/src/g_vumeter.c
+++ b/pd/src/g_vumeter.c
@@ -110,10 +110,8 @@ static void vu_draw_new(t_vu *x, t_glist *glist)
     int k1=x->x_led_size+1, k2=IEM_VU_STEPS+1, k3=k1/2;
     int led_col, yyy, i, k4=ypos-k3;
 
-    t_scalehandle *sh = (t_scalehandle *)x->x_gui.x_handle;
-    sprintf(sh->h_pathname, ".x%lx.h%lx", (t_int)canvas, (t_int)sh);
-    t_scalehandle *lh = (t_scalehandle *)x->x_gui.x_lhandle;
-    sprintf(lh->h_pathname, ".x%lx.h%lx", (t_int)canvas, (t_int)lh);
+    scalehandle_draw_new(x->x_gui. x_handle,canvas);
+    scalehandle_draw_new(x->x_gui.x_lhandle,canvas);
 
     //if (glist_isvisible(canvas)) {
 
@@ -497,13 +495,11 @@ static void vu__clickhook(t_scalehandle *sh, t_floatarg f, t_floatarg xxx,
 
     if (xxx)
     {
-        x->x_gui.scale_offset_x = xxx;
-        x->x_gui.label_offset_x = xxx;
+        sh->h_offset_x = xxx;
     }
     if (yyy)
     {
-        x->x_gui.scale_offset_y = yyy;
-        x->x_gui.label_offset_y = yyy;
+        sh->h_offset_y = yyy;
     }
 
     int newstate = (int)f;
@@ -517,10 +513,10 @@ static void vu__clickhook(t_scalehandle *sh, t_floatarg f, t_floatarg xxx,
         if (sh->h_dragx || sh->h_dragy)
         {
 
-            x->x_gui.x_w = x->x_gui.x_w + sh->h_dragx - x->x_gui.scale_offset_x;
+            x->x_gui.x_w = x->x_gui.x_w + sh->h_dragx - sh->h_offset_x;
             if (x->x_gui.x_w < SCALE_BNG_MINWIDTH)
                 x->x_gui.x_w = SCALE_BNG_MINWIDTH;
-            x->x_gui.x_h = x->x_gui.x_h + sh->h_dragy - x->x_gui.scale_offset_y;
+            x->x_gui.x_h = x->x_gui.x_h + sh->h_dragy - sh->h_offset_y;
             if (x->x_gui.x_h < SCALE_BNG_MINHEIGHT)
                 x->x_gui.x_h = SCALE_BNG_MINHEIGHT;
 
@@ -579,9 +575,9 @@ static void vu__clickhook(t_scalehandle *sh, t_floatarg f, t_floatarg xxx,
         {
 
             x->x_gui.x_ldx = x->x_gui.x_ldx +
-                sh->h_dragx - x->x_gui.label_offset_x;
+                sh->h_dragx - sh->h_offset_x;
             x->x_gui.x_ldy = x->x_gui.x_ldy +
-                sh->h_dragy - x->x_gui.label_offset_y;
+                sh->h_dragy - sh->h_offset_y;
 
             canvas_dirty(x->x_gui.x_glist, 1);
         }
@@ -612,7 +608,7 @@ static void vu__clickhook(t_scalehandle *sh, t_floatarg f, t_floatarg xxx,
         if (glist_isvisible(x->x_gui.x_glist))
         {
             sys_vgui("lower %s\n", sh->h_pathname);
-            t_scalehandle *othersh = (t_scalehandle *)x->x_gui.x_handle;
+            t_scalehandle *othersh = x->x_gui.x_handle;
             sys_vgui("lower .x%lx.h%lx\n",
                 (t_int)glist_getcanvas(x->x_gui.x_glist), (t_int)othersh);
         }
@@ -633,12 +629,12 @@ static void vu__motionhook(t_scalehandle *sh,
         int dx = (int)f1, dy = (int)f2;
         int newx, newy;
 
-        int y_incr = (int)((dy - x->x_gui.scale_offset_y) / IEM_VU_STEPS);
-        if (dy - x->x_gui.scale_offset_y < 0)
+        int y_incr = (int)((dy - sh->h_offset_y) / IEM_VU_STEPS);
+        if (dy - sh->h_offset_y < 0)
             y_incr -= 1;
 
         newx = x->x_gui.x_obj.te_xpix +
-            x->x_gui.x_w - x->x_gui.scale_offset_x + dx;
+            x->x_gui.x_w - sh->h_offset_x + dx;
         newy = x->x_gui.x_obj.te_ypix +
             x->x_gui.x_h + y_incr * IEM_VU_STEPS;
 
@@ -660,8 +656,8 @@ static void vu__motionhook(t_scalehandle *sh,
 
         if (properties)
         {
-            int new_w = x->x_gui.x_w - x->x_gui.scale_offset_x + sh->h_dragx;
-            int new_h = x->x_gui.x_h - x->x_gui.scale_offset_y + sh->h_dragy;
+            int new_w = x->x_gui.x_w - sh->h_offset_x + sh->h_dragx;
+            int new_h = x->x_gui.x_h - sh->h_offset_y + sh->h_dragy;
             sys_vgui(".gfxstub%lx.dim.w_ent delete 0 end\n", properties);
             sys_vgui(".gfxstub%lx.dim.w_ent insert 0 %d\n", properties, new_w);
             sys_vgui(".gfxstub%lx.dim.h_ent delete 0 end\n", properties);
@@ -680,8 +676,8 @@ static void vu__motionhook(t_scalehandle *sh,
 
         if (properties)
         {
-            int new_x = x->x_gui.x_ldx - x->x_gui.label_offset_x + sh->h_dragx;
-            int new_y = x->x_gui.x_ldy - x->x_gui.label_offset_y + sh->h_dragy;
+            int new_x = x->x_gui.x_ldx - sh->h_offset_x + sh->h_dragx;
+            int new_y = x->x_gui.x_ldy - sh->h_offset_y + sh->h_dragy;
             sys_vgui(".gfxstub%lx.label.xy.x_entry delete 0 end\n", properties);
             sys_vgui(".gfxstub%lx.label.xy.x_entry insert 0 %d\n",
                 properties, new_x);
@@ -697,8 +693,8 @@ static void vu__motionhook(t_scalehandle *sh,
             t_canvas *canvas=glist_getcanvas(x->x_gui.x_glist);
             sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",
                  canvas, x,
-                 xpos+x->x_gui.x_ldx + sh->h_dragx - x->x_gui.label_offset_x,
-                 ypos+x->x_gui.x_ldy + sh->h_dragy - x->x_gui.label_offset_y);
+                 xpos+x->x_gui.x_ldx + sh->h_dragx - sh->h_offset_x,
+                 ypos+x->x_gui.x_ldy + sh->h_dragy - sh->h_offset_y);
         }
     }
 }
@@ -1147,36 +1143,8 @@ static void *vu_new(t_symbol *s, int argc, t_atom *argv)
     x->x_out_rms = outlet_new(&x->x_gui.x_obj, &s_float);
     x->x_out_peak = outlet_new(&x->x_gui.x_obj, &s_float);
 
-    /* scale handle init */
-    t_scalehandle *sh;
-    char buf[64];
-    x->x_gui.x_handle = pd_new(scalehandle_class);
-    sh = (t_scalehandle *)x->x_gui.x_handle;
-    sh->h_master = (t_gobj*)x;
-    sprintf(buf, "_h%lx", (t_int)sh);
-    pd_bind(x->x_gui.x_handle, sh->h_bindsym = gensym(buf));
-    sprintf(sh->h_outlinetag, "h%lx", (t_int)sh);
-    sh->h_dragon = 0;
-    sh->h_scale = 1;
-    x->x_gui.scale_offset_x = 0;
-    x->x_gui.scale_offset_y = 0;
-    x->x_gui.scale_vis = 0;
-
-    /* label handle init */
-    t_scalehandle *lh;
-    char lhbuf[64];
-    x->x_gui.x_lhandle = pd_new(scalehandle_class);
-    lh = (t_scalehandle *)x->x_gui.x_lhandle;
-    lh->h_master = (t_gobj*)x;
-    sprintf(lhbuf, "_h%lx", (t_int)lh);
-    pd_bind(x->x_gui.x_lhandle, lh->h_bindsym = gensym(lhbuf));
-    sprintf(lh->h_outlinetag, "h%lx", (t_int)lh);
-    lh->h_dragon = 0;
-    lh->h_scale = 0;
-    x->x_gui.label_offset_x = 0;
-    x->x_gui.label_offset_y = 0;
-    x->x_gui.label_vis = 0;
-
+    x->x_gui. x_handle = scalehandle_new(scalehandle_class,(t_iemgui *)x,1);
+    x->x_gui.x_lhandle = scalehandle_new(scalehandle_class,(t_iemgui *)x,0);
     x->x_gui.x_obj.te_iemgui = 1;
 
     return (x);
@@ -1188,21 +1156,8 @@ static void vu_free(t_vu *x)
         pd_unbind(&x->x_gui.x_obj.ob_pd, x->x_gui.x_rcv);
     gfxstub_deleteforkey(x);
 
-    /* scale handle deconstructor */
-    if (x->x_gui.x_handle)
-    {
-        pd_unbind(x->x_gui.x_handle,
-            ((t_scalehandle *)x->x_gui.x_handle)->h_bindsym);
-        pd_free(x->x_gui.x_handle);
-    }
-
-    /* label handle deconstructor */
-    if (x->x_gui.x_lhandle)
-    {
-        pd_unbind(x->x_gui.x_lhandle,
-            ((t_scalehandle *)x->x_gui.x_lhandle)->h_bindsym);
-        pd_free(x->x_gui.x_lhandle);
-    }
+    if (x->x_gui. x_handle) scalehandle_free(x->x_gui. x_handle);
+    if (x->x_gui.x_lhandle) scalehandle_free(x->x_gui.x_lhandle);
 }
 
 void g_vumeter_setup(void)
-- 
GitLab