g_all_guis.c 41.5 KB
Newer Older
Miller Puckette's avatar
Miller Puckette committed
1 2 3 4 5 6 7
/* Copyright (c) 1997-1999 Miller Puckette.
 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
 * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */

/* g_7_guis.c written by Thomas Musil (c) IEM KUG Graz Austria 2000-2001 */
/* thanks to Miller Puckette, Guenther Geiger and Krzystof Czaja */

Hans-Christoph Steiner's avatar
Hans-Christoph Steiner committed
8
#include "config.h"
Miller Puckette's avatar
Miller Puckette committed
9 10 11 12 13 14 15

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include "m_pd.h"
#include "g_canvas.h"
16
#include "m_imp.h"
Miller Puckette's avatar
Miller Puckette committed
17 18 19
#include "g_all_guis.h"
#include <math.h>

20
t_symbol *s_empty;
21
t_class *scalehandle_class;
22

23 24 25 26
int iemgui_color_hex[] = {
    0xfcfcfc, 0xa0a0a0, 0x404040, 0xfce0e0, 0xfce0c0, 0xfcfcc8, 0xd8fcd8, 0xd8fcfc, 0xdce4fc, 0xf8d8fc,
    0xe0e0e0, 0x7c7c7c, 0x202020, 0xfc2828, 0xfcac44, 0xe8e828, 0x14e814, 0x28f4f4, 0x3c50fc, 0xf430f0,
    0xbcbcbc, 0x606060, 0x000000, 0x8c0808, 0x583000, 0x782814, 0x285014, 0x004450, 0x001488, 0x580050
Miller Puckette's avatar
Miller Puckette committed
27 28
};

29 30
int iemgui_clip_size(int size) {return maxi(size,IEM_GUI_MINSIZE);}
int iemgui_clip_font(int size) {return maxi(size,IEM_FONT_MINSIZE);}
31
static void scalehandle_check_and_redraw(t_iemgui *x);
Miller Puckette's avatar
Miller Puckette committed
32

33 34 35 36 37 38 39 40
/* helper function to negate legacy draw offset for labels
*/
void iemgui_getrect_legacy_label(t_iemgui *x, int *xp1, int *yp1)
{
    *xp1 -= x->legacy_x;
    *yp1 -= x->legacy_y;
}

41
static int iemgui_modulo_color(int col)
Miller Puckette's avatar
Miller Puckette committed
42
{
43
    const int IEM_GUI_MAX_COLOR = 30;
44 45 46
    col %= IEM_GUI_MAX_COLOR;
    if (col<0) col += IEM_GUI_MAX_COLOR;
    return col;
Miller Puckette's avatar
Miller Puckette committed
47 48 49 50 51 52 53 54 55
}

t_symbol *iemgui_dollar2raute(t_symbol *s)
{
    char buf[MAXPDSTRING+1], *s1, *s2;
    if (strlen(s->s_name) >= MAXPDSTRING)
        return (s);
    for (s1 = s->s_name, s2 = buf; ; s1++, s2++)
    {
56
        if (*s1 == '$' && *s1 && isdigit(s1[1]))
Miller Puckette's avatar
Miller Puckette committed
57 58 59 60 61 62 63 64 65 66 67 68 69 70
            *s2 = '#';
        else if (!(*s2 = *s1))
            break;
    }
    return(gensym(buf));
}

t_symbol *iemgui_raute2dollar(t_symbol *s)
{
    char buf[MAXPDSTRING+1], *s1, *s2;
    if (strlen(s->s_name) >= MAXPDSTRING)
        return (s);
    for (s1 = s->s_name, s2 = buf; ; s1++, s2++)
    {
71
        if (*s1 == '#' && *s1 && isdigit(s1[1]))
Miller Puckette's avatar
Miller Puckette committed
72 73 74 75 76 77 78
            *s2 = '$';
        else if (!(*s2 = *s1))
            break;
    }
    return(gensym(buf));
}

79
void iemgui_verify_snd_ne_rcv(t_iemgui *x)
Miller Puckette's avatar
Miller Puckette committed
80
{
81 82
    x->x_put_in2out = 
        !(iemgui_has_snd(x) && iemgui_has_rcv(x) && x->x_snd==x->x_rcv);
Miller Puckette's avatar
Miller Puckette committed
83 84
}

85
t_symbol *iemgui_getfloatsym(t_atom *a)
Miller Puckette's avatar
Miller Puckette committed
86
{
87 88 89 90 91
    if (IS_A_SYMBOL(a,0)) return (atom_getsymbol(a));
    if (IS_A_FLOAT(a,0)) {
        char str[40];
        sprintf(str, "%d", (int)atom_getint(a));
        return gensym(str);
Miller Puckette's avatar
Miller Puckette committed
92
    }
93 94 95 96 97 98
    return s_empty;
}
t_symbol *iemgui_getfloatsymarg(int i, int argc, t_atom *argv)
{
    if (i>=0 && i<argc) return iemgui_getfloatsym(argv+i);
    return s_empty;
Miller Puckette's avatar
Miller Puckette committed
99 100
}

101
void iemgui_new_getnames(t_iemgui *x, int indx, t_atom *argv)
Miller Puckette's avatar
Miller Puckette committed
102 103 104
{
    if (argv)
    {
105 106 107
        x->x_snd = iemgui_getfloatsym(argv+indx+0);
        x->x_rcv = iemgui_getfloatsym(argv+indx+1);
        x->x_lab = iemgui_getfloatsym(argv+indx+2);
Miller Puckette's avatar
Miller Puckette committed
108
    }
109 110 111 112
    else x->x_snd = x->x_rcv = x->x_lab = s_empty;
    x->x_snd_unexpanded = x->x_rcv_unexpanded = x->x_lab_unexpanded = 0;
    x->x_binbufindex = indx;
    x->x_labelbindex = indx + 3;
Miller Puckette's avatar
Miller Puckette committed
113 114
}

115 116 117 118
/* initialize a single symbol in unexpanded form.  We reach into the
   binbuf to grab them; if there's nothing there, set it to the
   fallback; if still nothing, set to "empty". */
static void iemgui_init_sym2dollararg(t_iemgui *x, t_symbol **symp,
Miller Puckette's avatar
Miller Puckette committed
119 120 121 122
    int indx, t_symbol *fallback)
{
    if (!*symp)
    {
123
        t_binbuf *b = x->x_obj.ob_binbuf;
Miller Puckette's avatar
Miller Puckette committed
124 125 126 127 128 129 130 131
        if (binbuf_getnatom(b) > indx)
        {
            char buf[80];
            atom_string(binbuf_getvec(b) + indx, buf, 80);
            *symp = gensym(buf);
        }
        else if (fallback)
            *symp = fallback;
132
        else *symp = s_empty;
Miller Puckette's avatar
Miller Puckette committed
133 134 135
    }
}

136
/* get the unexpanded versions of the symbols; initialize them if necessary. */
137
void iemgui_all_sym2dollararg(t_iemgui *x, t_symbol **srlsym)
Miller Puckette's avatar
Miller Puckette committed
138
{
139 140 141 142 143 144
    iemgui_init_sym2dollararg(x, &x->x_snd_unexpanded, x->x_binbufindex+1, x->x_snd);
    iemgui_init_sym2dollararg(x, &x->x_rcv_unexpanded, x->x_binbufindex+2, x->x_rcv);
    iemgui_init_sym2dollararg(x, &x->x_lab_unexpanded, x->x_labelbindex, x->x_lab);
    srlsym[0] = x->x_snd_unexpanded;
    srlsym[1] = x->x_rcv_unexpanded;
    srlsym[2] = x->x_lab_unexpanded;
Miller Puckette's avatar
Miller Puckette committed
145 146
}

147 148 149
static int col2save(int col) {
    return -1-(((0xfc0000 & col) >> 6)|((0xfc00 & col) >> 4)|((0xfc & col) >> 2));
}
150
void iemgui_all_col2save(t_iemgui *x, int *bflcol)
Miller Puckette's avatar
Miller Puckette committed
151
{
152 153 154
    bflcol[0] = col2save(x->x_bcol);
    bflcol[1] = col2save(x->x_fcol);
    bflcol[2] = col2save(x->x_lcol);
Miller Puckette's avatar
Miller Puckette committed
155 156
}

157 158
static int colfromload(int col) {
    if(col)
Miller Puckette's avatar
Miller Puckette committed
159
    {
160 161
        col = -1-col;
        return ((col & 0x3f000) << 6)|((col & 0xfc0) << 4)|((col & 0x3f) << 2);
Miller Puckette's avatar
Miller Puckette committed
162 163
    }
    else
164 165
        return iemgui_color_hex[iemgui_modulo_color(col)];
}
166
void iemgui_all_colfromload(t_iemgui *x, int *bflcol)
167
{
168 169 170
    x->x_bcol = colfromload(bflcol[0]);
    x->x_fcol = colfromload(bflcol[1]);
    x->x_lcol = colfromload(bflcol[2]);
Miller Puckette's avatar
Miller Puckette committed
171 172
}

173
static int iemgui_compatible_col(int i)
Miller Puckette's avatar
Miller Puckette committed
174 175
{
    if(i >= 0)
176 177
        return(iemgui_color_hex[(iemgui_modulo_color(i))]);
    return((-1-i)&0xffffff);
Miller Puckette's avatar
Miller Puckette committed
178 179 180 181 182 183 184 185 186
}

void iemgui_all_raute2dollar(t_symbol **srlsym)
{
    srlsym[0] = iemgui_raute2dollar(srlsym[0]);
    srlsym[1] = iemgui_raute2dollar(srlsym[1]);
    srlsym[2] = iemgui_raute2dollar(srlsym[2]);
}

187
void iemgui_send(t_iemgui *x, t_symbol *s)
Miller Puckette's avatar
Miller Puckette committed
188 189
{
    t_symbol *snd;
190
    if (s == &s_) s = s_empty; //tb: fix for empty label
191 192 193
    int oldsndrcvable=0;
    if(iemgui_has_rcv(x)) oldsndrcvable += IEM_GUI_OLD_RCV_FLAG;
    if(iemgui_has_snd(x)) oldsndrcvable += IEM_GUI_OLD_SND_FLAG;
Miller Puckette's avatar
Miller Puckette committed
194 195

    snd = iemgui_raute2dollar(s);
196 197 198
    x->x_snd_unexpanded = snd;
    x->x_snd = snd = canvas_realizedollar(x->x_glist, snd);
    iemgui_verify_snd_ne_rcv(x);
199
    iemgui_draw_io(x, oldsndrcvable);
Miller Puckette's avatar
Miller Puckette committed
200 201
}

202
void iemgui_receive(t_iemgui *x, t_symbol *s)
Miller Puckette's avatar
Miller Puckette committed
203 204
{
    t_symbol *rcv;
205
    if (s == &s_) s = s_empty; //tb: fix for empty label
206 207 208
    int oldsndrcvable=0;
    if(iemgui_has_rcv(x)) oldsndrcvable += IEM_GUI_OLD_RCV_FLAG;
    if(iemgui_has_snd(x)) oldsndrcvable += IEM_GUI_OLD_SND_FLAG;
Miller Puckette's avatar
Miller Puckette committed
209 210

    rcv = iemgui_raute2dollar(s);
211 212
    x->x_rcv_unexpanded = rcv;
    rcv = canvas_realizedollar(x->x_glist, rcv);
213
    if(s!=s_empty)
Miller Puckette's avatar
Miller Puckette committed
214
    {
215
        if(rcv!=x->x_rcv)
Miller Puckette's avatar
Miller Puckette committed
216
        {
217 218 219 220
            if(iemgui_has_rcv(x))
                pd_unbind((t_pd *)x, x->x_rcv);
            x->x_rcv = rcv;
            pd_bind((t_pd *)x, x->x_rcv);
Miller Puckette's avatar
Miller Puckette committed
221 222
        }
    }
223
    else if(s==s_empty && iemgui_has_rcv(x))
Miller Puckette's avatar
Miller Puckette committed
224
    {
225 226
        pd_unbind((t_pd *)x, x->x_rcv);
        x->x_rcv = rcv;
Miller Puckette's avatar
Miller Puckette committed
227
    }
228
    iemgui_verify_snd_ne_rcv(x);
229
    iemgui_draw_io(x, oldsndrcvable);
Miller Puckette's avatar
Miller Puckette committed
230 231
}

232
void iemgui_label(t_iemgui *x, t_symbol *s)
Miller Puckette's avatar
Miller Puckette committed
233
{
234
    t_symbol *old;
235
    if (s == &s_) s = s_empty; //tb: fix for empty label
236
    old = x->x_lab;
237 238 239
    t_symbol *lab = iemgui_raute2dollar(s);
    x->x_lab_unexpanded = lab;
    x->x_lab = lab = canvas_realizedollar(x->x_glist, lab);
Miller Puckette's avatar
Miller Puckette committed
240

241
    if (glist_isvisible(x->x_glist) && lab != old)
242
        iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_CONFIG);
Miller Puckette's avatar
Miller Puckette committed
243 244
}

245
void iemgui_label_pos(t_iemgui *x, t_symbol *s, int ac, t_atom *av)
Miller Puckette's avatar
Miller Puckette committed
246
{
247 248
    x->x_ldx = atom_getintarg(0, ac, av);
    x->x_ldy = atom_getintarg(1, ac, av);
249
    if(glist_isvisible(x->x_glist))
250
    {
251 252 253 254
        int x1 = x->x_ldx;
        int y1 = x->x_ldy;
        //iemgui_getrect_legacy_label(x, &x1, &y1);

255 256 257
        gui_vmess("gui_iemgui_label_coords", "xxii",
            glist_getcanvas(x->x_glist),
            x,
258 259
            x1,
            y1);
260
        iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_CONFIG);
261
    }
Miller Puckette's avatar
Miller Puckette committed
262 263
}

264
void iemgui_label_font(t_iemgui *x, t_symbol *s, int ac, t_atom *av)
Miller Puckette's avatar
Miller Puckette committed
265
{
266
    int f = atom_getintarg(0, ac, av);
267 268
    if (f<0 || f>2) f=0;
    x->x_font_style = f;
269
    x->x_fontsize = maxi(atom_getintarg(1, ac, av),4);
270
    if(glist_isvisible(x->x_glist))
271
    {
272
        gui_vmess("gui_iemgui_label_font", "xxssi",
273 274
            glist_getcanvas(x->x_glist),
            x,
275 276 277
            iemgui_typeface(x),
            sys_fontweight,
            x->x_fontsize);
278
        iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_CONFIG);
279
    }
280 281 282 283 284 285
}

//Sans: 84 x 10 (14) -> 6 x 10 -> 1.0
//Helvetica: 70 x 10 (14) -> 5 x 10 -> 0.83333
//Times: 61 x 10 (14) -> 4.357 x 10 -> 0.72619; 0.735 appears to work better

286 287 288 289 290 291
// We use this global var to check when getrect should report label:
// It should report it when drawing inside gop to see if we truly fit.
// Otherwise we should not report it while inside gop to avoid label being
// misinterpreted as part of the "hot" area of a widget (e.g. toggle)
extern int gop_redraw;

292 293 294 295
void iemgui_label_getrect(t_iemgui x_gui, t_glist *x,
    int *xp1, int *yp1, int *xp2, int *yp2)
{
    //fprintf(stderr,"gop_redraw = %d\n", gop_redraw);
296
    if (!gop_redraw || sys_legacy)
297 298
    {
        //fprintf(stderr,"ignoring label\n");
299
        return;
300 301 302
    }

    t_float width_multiplier;
303
    int label_length;
304 305 306 307
    int label_x1;
    int label_y1;
    int label_x2;
    int label_y2;
308
    int actual_fontsize; //seems tk does its own thing when rendering
309 310 311 312
    int actual_height;

    if (x->gl_isgraph && !glist_istoplevel(x))
    {
313
        if (x_gui.x_lab!=s_empty)
314
        {
315
            switch(x_gui.x_font_style)
316
            {
317 318 319
                case 1:  width_multiplier = 0.83333; break;
                case 2:  width_multiplier = 0.735;   break;
                default: width_multiplier = 1.0;     break;
320
            }
321
            actual_fontsize = x_gui.x_fontsize;
322
            actual_height = actual_fontsize;
323
            //exceptions
324
            if (x_gui.x_font_style == 0 &&
325 326 327 328 329 330 331
                (actual_fontsize == 8 || actual_fontsize == 13 ||
                actual_fontsize % 10 == 1 || actual_fontsize % 10 == 6 ||
                    (actual_fontsize > 48 && actual_fontsize < 100 &&
                    (actual_fontsize %10 == 4 || actual_fontsize %10 == 9))))
            {
                actual_fontsize += 1;
            }
332
            else if (x_gui.x_font_style == 1 && actual_fontsize >= 5 &&
333 334
                actual_fontsize < 13 && actual_fontsize % 2 == 1)
                actual_fontsize += 1;
335
            else if (x_gui.x_font_style == 2 && actual_fontsize >= 5 &&
336 337 338 339 340 341 342 343 344 345 346 347 348 349 350
                actual_fontsize % 2 == 1)
                actual_fontsize += 1;
            if (actual_height == 9)
                actual_height += 1;
            //done with exceptions

            width_multiplier = width_multiplier * (actual_fontsize * 0.6);

            label_length = strlen(x_gui.x_lab->s_name);
            label_x1 = *xp1 + x_gui.x_ldx;
            label_y1 = *yp1 + x_gui.x_ldy - actual_height/2;
            label_x2 = label_x1 + (label_length * width_multiplier);
            label_y2 = label_y1 + actual_height*1.1;

            //DEBUG
351 352
            // Note: we may want to port this debug code to the
            // new interface, but we haven't had a need to do it yet
353
            //fprintf(stderr,"%f %d %d\n", width_multiplier,
354
            //    label_length, x_gui.x_font_style);
355 356 357 358 359 360 361 362 363 364 365 366 367 368
            //sys_vgui(".x%lx.c delete iemguiDEBUG\n", x);
            //sys_vgui(".x%lx.c create rectangle %d %d %d %d "
            //    "-tags iemguiDEBUG\n",
            //    x, label_x1, label_y1, label_x2, label_y2);
            if (label_x1 < *xp1) *xp1 = label_x1;
            if (label_x2 > *xp2) *xp2 = label_x2;
            if (label_y1 < *yp1) *yp1 = label_y1;
            if (label_y2 > *yp2) *yp2 = label_y2;
            //DEBUG
            //sys_vgui(".x%lx.c delete iemguiDEBUG\n", x);
            //sys_vgui(".x%lx.c create rectangle %d %d %d %d "
            //    "-tags iemguiDEBUG\n", x, *xp1, *yp1, *xp2, *yp2);
        }
    }
369 370
}

371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413
#if 0 // future way of reordering stuff for iemgui_shouldvis
/*
    // some day when the object tagging is
    // properly done for all GUI objects
    glist_noselect(canvas);
    glist_select(canvas, y);
    t_gobj *yy = canvas->gl_list;
    if (yy != y)
    {
        while (yy && yy->g_next != y)
            yy = yy->g_next;
        // now we have yy which is right before our y graph
        t_rtext *yr = NULL;
        if (yy)
        {
            yr = glist_findrtext(canvas, (t_text *)yy);
        }
        if (yr)
        {
            fprintf(stderr,"lower\n");
            sys_vgui(".x%lx.c lower selected %s\n", canvas, rtext_gettag(yr));
            sys_vgui(".x%lx.c raise selected %s\n", canvas, rtext_gettag(yr));
            //canvas_raise_all_cords(canvas);
        }
        else
        {
            // fall back to legacy redraw for objects
            //   that are not patchable
            fprintf(stderr,"lower fallback redraw\n");
            canvas_redraw(canvas);
        }
    }
    else
    {
        // we get here if we are supposed to go
        //   all the way to the bottom
        fprintf(stderr,"lower to the bottom\n");
        sys_vgui(".x%lx.c lower selected\n", canvas);
    }
    glist_noselect(canvas);
*/
#endif

414
void iemgui_shouldvis(t_iemgui *x, int mode)
415
{
416
    gop_redraw = 1;
417
    if(gobj_shouldvis((t_gobj *)x, x->x_glist))
418
    {
419
        if (!x->x_vis)
420 421
        {
            //fprintf(stderr,"draw new %d\n", mode);
422
            iemgui_draw_new(x);
423 424 425
            canvas_fixlinesfor(glist_getcanvas(x->x_glist), (t_text*)x);
            x->x_vis = 1;
            if (x->x_glist != glist_getcanvas(x->x_glist))
426 427 428 429
            {
                /* if we are inside gop and just have had our object's
                   properties changed we'll adjust our layer position
                   to ensure that ordering is honored */
430
                t_canvas *canvas = glist_getcanvas(x->x_glist);
431
                //t_gobj *y = (t_gobj *)x->x_glist;
432 433 434 435 436 437
                // this crashes when the label goes invisible and then
                // needs to be made visible again, so for the time being
                // we use the brute force redraw below for both the
                // vis/unvis-ing of the object and its reordering
                //gobj_vis(y, canvas, 0);
                //gobj_vis(y, canvas, 1);
438 439 440 441
                // reorder it visually
                glist_redraw(canvas);
            }
        }
442
        //fprintf(stderr,"draw move x->x_w=%d\n", x->x_w);
443 444 445 446
        if      (mode==IEM_GUI_DRAW_MODE_NEW)    iemgui_draw_new(   x);
        else if (mode==IEM_GUI_DRAW_MODE_MOVE)   iemgui_draw_move(  x);
        else if (mode==IEM_GUI_DRAW_MODE_CONFIG) iemgui_draw_config(x);
        else bug("iemgui_shouldvis");
447
        scalehandle_check_and_redraw(x);
448
        canvas_fixlinesfor(glist_getcanvas(x->x_glist), (t_text*)x);
449
    }
450
    else if (x->x_vis)
451 452
    {
        //fprintf(stderr,"draw erase %d\n", mode);
453
        iemgui_draw_erase(x);
454
        x->x_vis = 0;
455 456
    }
    gop_redraw = 0;
Miller Puckette's avatar
Miller Puckette committed
457 458
}

459
void iemgui_size(t_iemgui *x)
Miller Puckette's avatar
Miller Puckette committed
460
{
Jonathan Wilkes's avatar
Jonathan Wilkes committed
461
    if (glist_isvisible(x->x_glist))
462
        iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_MOVE);
Miller Puckette's avatar
Miller Puckette committed
463 464
}

465
void iemgui_delta(t_iemgui *x, t_symbol *s, int ac, t_atom *av)
Miller Puckette's avatar
Miller Puckette committed
466
{
467 468
    x->x_obj.te_xpix += atom_getintarg(0, ac, av);
    x->x_obj.te_ypix += atom_getintarg(1, ac, av);
469 470
    if(glist_isvisible(x->x_glist))
        iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_MOVE);
Miller Puckette's avatar
Miller Puckette committed
471 472
}

473
void iemgui_pos(t_iemgui *x, t_symbol *s, int ac, t_atom *av)
Miller Puckette's avatar
Miller Puckette committed
474
{
475 476
    x->x_obj.te_xpix = atom_getintarg(0, ac, av);
    x->x_obj.te_ypix = atom_getintarg(1, ac, av);
477 478
    if(glist_isvisible(x->x_glist))
        iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_MOVE);
Miller Puckette's avatar
Miller Puckette committed
479 480
}

481
void iemgui_color(t_iemgui *x, t_symbol *s, int ac, t_atom *av)
Miller Puckette's avatar
Miller Puckette committed
482
{
483
    x->x_bcol = iemgui_compatible_col(atom_getintarg(0, ac, av));
Miller Puckette's avatar
Miller Puckette committed
484 485
    if(ac > 2)
    {
486 487
        x->x_fcol = iemgui_compatible_col(atom_getintarg(1, ac, av));
        x->x_lcol = iemgui_compatible_col(atom_getintarg(2, ac, av));
Miller Puckette's avatar
Miller Puckette committed
488 489
    }
    else
490 491
        x->x_lcol = iemgui_compatible_col(atom_getintarg(1, ac, av));
    if(glist_isvisible(x->x_glist))
492
    {
493
        x->x_draw(x, x->x_glist, IEM_GUI_DRAW_MODE_CONFIG);
494 495
        iemgui_label_draw_config(x);
    }
Miller Puckette's avatar
Miller Puckette committed
496 497 498 499
}

void iemgui_displace(t_gobj *z, t_glist *glist, int dx, int dy)
{
500 501 502
    t_iemgui *x = (t_iemgui *)z;
    x->x_obj.te_xpix += dx;
    x->x_obj.te_ypix += dy;
503 504
    if (glist_isvisible(glist))
        iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_MOVE);
Miller Puckette's avatar
Miller Puckette committed
505 506
}

507 508
void iemgui_displace_withtag(t_gobj *z, t_glist *glist, int dx, int dy)
{
509 510 511
    t_iemgui *x = (t_iemgui *)z;
    x->x_obj.te_xpix += dx;
    x->x_obj.te_ypix += dy;
512
    //iemgui_draw_move(x);
513 514 515
    canvas_fixlinesfor(glist_getcanvas(glist), (t_text *)z);
}

Miller Puckette's avatar
Miller Puckette committed
516 517
void iemgui_select(t_gobj *z, t_glist *glist, int selected)
{
518
    t_iemgui *x = (t_iemgui *)z;
519
    t_canvas *canvas=glist_getcanvas(glist);
520 521 522 523
    if (selected)
        x->x_selected = canvas;
    else
        x->x_selected = NULL;
524
    x->x_draw((void *)z, glist, IEM_GUI_DRAW_MODE_SELECT);
525 526 527 528 529 530 531 532 533 534 535 536 537 538
    if (selected < 2)
    {
        scalehandle_draw(x);
    }
    else
    {
        // exception where we get rid of handles when moving tiny objects
        // because tkpath's slowness sometimes makes mouse pointer go over
        // a handle and messes things up. we only do this when using
        // startmotion (see g_editor.c).
        // LATER: get rid of this because we will deal with this better using
        // the new toolkit.
        scalehandle_draw_erase2(x);
    }
539 540
    iemgui_label_draw_select(x);
    iemgui_tag_selected(x);
Miller Puckette's avatar
Miller Puckette committed
541 542 543 544 545 546 547 548 549
}

void iemgui_delete(t_gobj *z, t_glist *glist)
{
    canvas_deletelinesfor(glist, (t_text *)z);
}

void iemgui_vis(t_gobj *z, t_glist *glist, int vis)
{
550
    t_iemgui *x = (t_iemgui *)z;
551 552 553
    if (gobj_shouldvis(z, glist))
    {
        if (vis)
554
            iemgui_draw_new(x);
555 556
        else
        {
557
            iemgui_draw_erase(x);
558 559
            sys_unqueuegui(z);
        }
560
        x->x_vis = vis;
561
    }
Miller Puckette's avatar
Miller Puckette committed
562 563
}

564
void iemgui_save(t_iemgui *x, t_symbol **srl, int *bflcol)
Miller Puckette's avatar
Miller Puckette committed
565
{
566 567 568 569 570 571 572
    if (srl) {
       srl[0] = x->x_snd;
       srl[1] = x->x_rcv;
       srl[2] = x->x_lab;
    }
    iemgui_all_sym2dollararg(x, srl);
    iemgui_all_col2save(x, bflcol);
Miller Puckette's avatar
Miller Puckette committed
573 574
}

575
void iemgui_properties(t_iemgui *x, t_symbol **srl)
Miller Puckette's avatar
Miller Puckette committed
576
{
577 578 579 580 581 582 583
    srl[0] = x->x_snd;
    srl[1] = x->x_rcv;
    srl[2] = x->x_lab;
    iemgui_all_sym2dollararg(x, srl);
    srl[0] = iemgui_dollar2raute(srl[0]);
    srl[1] = iemgui_dollar2raute(srl[1]);
    srl[2] = iemgui_dollar2raute(srl[2]);
Miller Puckette's avatar
Miller Puckette committed
584 585
}

586
int iemgui_dialog(t_iemgui *x, int argc, t_atom *argv)
Miller Puckette's avatar
Miller Puckette committed
587
{
588
    t_symbol *srl[3];
589 590 591 592 593 594 595 596 597 598 599 600
    x->x_loadinit = !!atom_getintarg(5, argc, argv);
    srl[0] = iemgui_getfloatsymarg(7,argc,argv);
    srl[1] = iemgui_getfloatsymarg(8,argc,argv);
    srl[2] = iemgui_getfloatsymarg(9,argc,argv);
    x->x_ldx = atom_getintarg(10, argc, argv);
    x->x_ldy = atom_getintarg(11, argc, argv);
    int f = atom_getintarg(12, argc, argv);
    x->x_fontsize = maxi(atom_getintarg(13, argc, argv),4);
    x->x_bcol = atom_getintarg(14, argc, argv) & 0xffffff;
    x->x_fcol = atom_getintarg(15, argc, argv) & 0xffffff;
    x->x_lcol = atom_getintarg(16, argc, argv) & 0xffffff;
    int oldsndrcvable=0;
601 602
    if(iemgui_has_rcv(x)) oldsndrcvable |= IEM_GUI_OLD_RCV_FLAG;
    if(iemgui_has_snd(x)) oldsndrcvable |= IEM_GUI_OLD_SND_FLAG;
Miller Puckette's avatar
Miller Puckette committed
603
    iemgui_all_raute2dollar(srl);
604 605 606 607 608 609 610 611 612 613 614 615 616

    // replace ascii code 11 (\v or vertical tab) with spaces
    // we do this so that the string with spaces can survive argc,argv
    // conversion when coming from dialog side of things where it is parsed
    char *c;
    for(c = srl[2]->s_name; c != NULL && *c != '\0'; c++)
    {
        if(*c == '\v')
        {
            *c = ' ';
        }
    }

617 618 619 620
    x->x_snd_unexpanded=srl[0]; srl[0]=canvas_realizedollar(x->x_glist, srl[0]);
    x->x_rcv_unexpanded=srl[1]; srl[1]=canvas_realizedollar(x->x_glist, srl[1]);
    x->x_lab_unexpanded=srl[2]; srl[2]=canvas_realizedollar(x->x_glist, srl[2]);
    if(srl[1]!=x->x_rcv)
Miller Puckette's avatar
Miller Puckette committed
621
    {
622 623 624 625
        if(iemgui_has_rcv(x))
            pd_unbind((t_pd *)x, x->x_rcv);
        x->x_rcv = srl[1];
        pd_bind((t_pd *)x, x->x_rcv);
Miller Puckette's avatar
Miller Puckette committed
626
    }
627 628
    x->x_snd = srl[0];
    x->x_lab = srl[2];
629
    if(f<0 || f>2) f=0;
630 631 632
    x->x_font_style = f;
    iemgui_verify_snd_ne_rcv(x);
    canvas_dirty(x->x_glist, 1);
633
    return oldsndrcvable;
Miller Puckette's avatar
Miller Puckette committed
634 635
}

636
void iem_inttosymargs(t_iemgui *x, int n)
Miller Puckette's avatar
Miller Puckette committed
637
{
638 639 640
    x->x_loadinit = (n >>  0);
    x->x_locked = 0;
    x->x_reverse = 0;
Miller Puckette's avatar
Miller Puckette committed
641 642
}

643
int iem_symargstoint(t_iemgui *x)
Miller Puckette's avatar
Miller Puckette committed
644
{
645
    return ((x->x_loadinit & 1) <<  0);
Miller Puckette's avatar
Miller Puckette committed
646 647
}

648
void iem_inttofstyle(t_iemgui *x, int n)
Miller Puckette's avatar
Miller Puckette committed
649
{
650
    x->x_font_style = (n >> 0);
651
    x->x_selected = NULL;
652 653 654 655 656 657
    x->x_finemoved = 0;
    x->x_put_in2out = 0;
    x->x_change = 0;
}

int iem_fstyletoint(t_iemgui *x)
Miller Puckette's avatar
Miller Puckette committed
658
{
659
    return ((x->x_font_style << 0) & 63);
Miller Puckette's avatar
Miller Puckette committed
660
}
661

662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677
char *iem_get_tag(t_canvas *glist, t_iemgui *iem_obj)
{
    t_gobj *y = (t_gobj *)iem_obj;
    t_object *ob = pd_checkobject(&y->g_pd);

    /* GOP objects are unable to call findrtext
       triggering consistency check error */
    t_rtext *yyyy = NULL;
    if (!glist->gl_isgraph || glist_istoplevel(glist))
        yyyy = glist_findrtext(glist_getcanvas(glist), (t_text *)&ob->ob_g);

    /* on GOP we cause segfault as text_gettag() returns bogus data */
    if (yyyy) return(rtext_gettag(yyyy));
    else return("bogus");
}

678
//----------------------------------------------------------------
679
// SCALEHANDLE COMMON CODE (by Mathieu, refactored from existing code)
680

681 682
extern int gfxstub_haveproperties(void *key);

683 684 685 686
int   mini(int   a, int   b) {return a<b?a:b;}
int   maxi(int   a, int   b) {return a>b?a:b;}
float minf(float a, float b) {return a<b?a:b;}
float maxf(float a, float b) {return a>b?a:b;}
687

688 689
extern t_class *my_canvas_class;

690
// in 18 cases only, because canvas does not fit the pattern below.
691 692
// canvas has no label handle and has a motion handle
// but in the case of canvas, the "iemgui" tag is added (it wasn't the case originally)
693 694
void scalehandle_draw_select(t_scalehandle *h, int px, int py)
{
695
    char tagbuf[MAXPDSTRING];
696
    t_object *x = h->h_master;
697
    t_canvas *canvas=glist_getcanvas(h->h_glist);
698 699 700 701

    int sx = h->h_scale ? SCALEHANDLE_WIDTH  : LABELHANDLE_WIDTH;
    int sy = h->h_scale ? SCALEHANDLE_HEIGHT : LABELHANDLE_HEIGHT;

702
    scalehandle_draw_erase(h);
703

704
    if (!h->h_vis) {
705
        sprintf(tagbuf, "x%lx", (long unsigned int)x);
706 707
        gui_vmess("gui_iemgui_label_show_drag_handle", "xsiiii",
            canvas, tagbuf, 1, px - sx, py - sy, h->h_scale);
708
        h->h_vis = 1;
709
    }
710 711
}

712 713
void scalehandle_draw_select2(t_iemgui *x)
{
714
    t_canvas *canvas=glist_getcanvas(x->x_glist);
715
    t_class *c = pd_class((t_pd *)x);
716
    int sx,sy;
717
    if (c == my_canvas_class)
718
    {
719
        t_my_canvas *y = (t_my_canvas *)x;
720 721
        sx = y->x_vis_w;
        sy = y->x_vis_h;
722 723 724
    }
    else
    {
725 726
        int x1,y1,x2,y2;
        c->c_wb->w_getrectfn((t_gobj *)x,canvas,&x1,&y1,&x2,&y2);
727
        //iemgui_getrect_draw(x, &x1, &y1, &x2, &y2);
728 729
        sx=x2-x1; sy=y2-y1;
    }
730 731
    /* we're not drawing the scalehandle for the actual iemgui-- just
       the one for the label. */
732
    if (c == my_canvas_class)
733
        scalehandle_draw_select(x->x_handle,sx+8,sy+3);
734
    if (x->x_lab != s_empty)
735
        scalehandle_draw_select(x->x_lhandle,x->x_ldx,x->x_ldy);
736 737
}

738 739 740
void scalehandle_draw_erase(t_scalehandle *h)
{
    //t_canvas *canvas = glist_getcanvas(h->h_glist);
741
    if (!h->h_vis) return;
742 743
    gui_vmess("gui_iemgui_label_show_drag_handle", "xxiiii",
        h->h_glist, h->h_master, 0, 0, 0, h->h_scale);
744
    h->h_vis = 0;
745 746
}

747 748
void scalehandle_draw_erase2(t_iemgui *x)
{
749 750
    t_scalehandle *sh = (t_scalehandle *)(x->x_handle);
    t_scalehandle *lh = (t_scalehandle *)(x->x_lhandle);
751 752
    if (sh->h_vis) scalehandle_draw_erase(sh);
    if (lh->h_vis) scalehandle_draw_erase(lh);
753 754
}

755 756 757 758
void scalehandle_draw(t_iemgui *x)
{
    if (x->x_glist == glist_getcanvas(x->x_glist))
    {
759
        if (x->x_selected == x->x_glist) scalehandle_draw_select2(x);
760
        else scalehandle_draw_erase2(x);
761
    }
762 763
}

764 765 766
t_scalehandle *scalehandle_new(t_object *x, t_glist *glist, int scale,
    t_clickhandlefn chf, t_motionhandlefn mhf)
{
767
    t_scalehandle *h = (t_scalehandle *)pd_new(scalehandle_class);
768 769
    char buf[19]; // 3 + max size of %lx
    h->h_master = x;
770
    h->h_glist = glist;
771 772
    if (!scale) /* Only bind for labels-- scaling uses pd_vmess in g_editor.c */
    {
773
        sprintf(buf, "_l%lx", (long unsigned int)x);
774 775 776 777
        pd_bind((t_pd *)h, h->h_bindsym = gensym(buf));
    }
    else if (scale && pd_class((t_pd *)x) == my_canvas_class)
    {
778
        sprintf(buf, "_s%lx", (long unsigned int)x);
779 780
        pd_bind((t_pd *)h, h->h_bindsym = gensym(buf));
    }
781 782 783
    sprintf(h->h_outlinetag, "h%lx", (t_int)h);
    h->h_dragon = 0;
    h->h_scale = scale;
784 785
    h->h_offset_x = 0;
    h->h_offset_y = 0;
786
    h->h_vis = 0;
787
    sprintf(h->h_pathname, ".x%lx.h%lx", (t_int)h->h_glist, (t_int)h);
788 789
    h->h_clickfn = chf;
    h->h_motionfn = mhf;
790 791 792
    return h;
}

793 794
void scalehandle_free(t_scalehandle *h)
{
795 796
    if (!h->h_scale || pd_class((t_pd *)(h->h_master)) == my_canvas_class)
    { /* only binding label handles and my_canvas resize handle */
797 798
        pd_unbind((t_pd *)h, h->h_bindsym);
    }
799
    pd_free((t_pd *)h);
800
}
801

802 803
void properties_set_field_int(long props, const char *gui_field, int value)
{
804 805 806 807 808 809
    char tagbuf[MAXPDSTRING];
    sprintf(tagbuf, ".gfxstub%lx", props);
    gui_vmess("gui_dialog_set_field", "ssi",
        tagbuf,
        gui_field,
        value);
810
}
811

812 813
void scalehandle_dragon_label(t_scalehandle *h, float mouse_x, float mouse_y)
{
814 815 816
    if (h->h_dragon && !h->h_scale)
    {
        t_iemgui *x = (t_iemgui *)(h->h_master);
817 818
        int dx = (int)mouse_x - (int)h->h_offset_x,
            dy = (int)mouse_y - (int)h->h_offset_y;
819 820
        h->h_dragx = dx;
        h->h_dragy = dy;
821

822 823 824
        int properties = gfxstub_haveproperties((void *)x);
        if (properties)
        {
825 826
            int new_x = x->x_ldx + h->h_dragx;
            int new_y = x->x_ldy + h->h_dragy;
827 828
            properties_set_field_int(properties, "x_offset", new_x);
            properties_set_field_int(properties, "y_offset", new_y);
829
        }
830 831 832
        x->x_ldx += dx;
        x->x_ldy += dy;

833 834
        if (glist_isvisible(x->x_glist))
        {
835 836
            //int xpos=text_xpix(&x->x_obj, x->x_glist);
            //int ypos=text_ypix(&x->x_obj, x->x_glist);
837
            //iemgui_getrect_legacy_label(x, &xpos, &ypos);
838
            t_canvas *canvas=glist_getcanvas(x->x_glist);
839 840 841 842 843
            gui_vmess("gui_iemgui_label_coords", "xxii",
                canvas,
                x,
                x->x_ldx,
                x->x_ldy);
844 845 846
        }
    }
}
847

848 849
void scalehandle_click_label(t_scalehandle *h)
{
850 851 852
    t_iemgui *x = (t_iemgui *)h->h_master;
    if (glist_isvisible(x->x_glist))
    {
853
        //sys_vgui("lower %s\n", h->h_pathname);
854
        //t_scalehandle *othersh = x->x_handle;
855 856
        //sys_vgui("lower .x%lx.h%lx\n",
        //    (t_int)glist_getcanvas(x->x_glist), (t_int)othersh);
857 858 859 860 861 862 863 864 865
    }
    h->h_dragx = 0;
    h->h_dragy = 0;
}

void scalehandle_getrect_master(t_scalehandle *h, int *x1, int *y1, int *x2, int *y2) {
    t_iemgui *x = (t_iemgui *)h->h_master;
    t_class *c = pd_class((t_pd *)x);
    c->c_wb->w_getrectfn((t_gobj *)x,x->x_glist,x1,y1,x2,y2);
866 867 868
    //fprintf(stderr,"%d %d %d %d\n",*x1,*y1,*x2,*y2);
    //iemgui_getrect_draw((t_iemgui *)x, x1, y1, x2, y2);
    //fprintf(stderr,"%d %d %d %d\n",*x1,*y1,*x2,*y2);
869 870 871 872 873 874 875 876 877 878 879 880
    //printf("%s\n",c->c_name->s_name);
    if (c==my_canvas_class) {
        t_my_canvas *xx = (t_my_canvas *)x;
        *x2=*x1+xx->x_vis_w;
        *y2=*y1+xx->x_vis_h;
    }
}

void scalehandle_click_scale(t_scalehandle *h) {
    int x1,y1,x2,y2;
    t_iemgui *x = (t_iemgui *)h->h_master;
    scalehandle_getrect_master(h,&x1,&y1,&x2,&y2);
Jonathan Wilkes's avatar
Jonathan Wilkes committed
881 882 883 884 885
    if (glist_isvisible(x->x_glist))
    {
        //sys_vgui("lower %s\n", h->h_pathname);
        //sys_vgui(".x%x.c create prect %d %d %d %d -stroke $pd_colors(selection) -strokewidth 1 -tags %s\n",
        //    x->x_glist, x1, y1, x2, y2, h->h_outlinetag);
886 887 888 889 890
    }
    h->h_dragx = 0;
    h->h_dragy = 0;
}

891 892 893
// here we don't need to use glist_getcanvas(t_canvas *)
// because scalehandle on iemgui objects appears only when
// they are on their own canvas
894 895
void scalehandle_unclick_scale(t_scalehandle *h) {
    t_iemgui *x = (t_iemgui *)h->h_master;
896
    //sys_vgui(".x%x.c delete %s\n", x->x_glist, h->h_outlinetag);
897
    iemgui_io_draw_move(x);
898 899
    iemgui_select((t_gobj *)x, x->x_glist, 1);
    canvas_fixlinesfor(x->x_glist, (t_text *)x);
900
    canvas_getscroll(x->x_glist);
901 902 903 904 905 906
}

void scalehandle_drag_scale(t_scalehandle *h) {
    int x1,y1,x2,y2;
    t_iemgui *x = (t_iemgui *)h->h_master;
    scalehandle_getrect_master(h,&x1,&y1,&x2,&y2);
Jonathan Wilkes's avatar
Jonathan Wilkes committed
907 908 909 910
    if (glist_isvisible(x->x_glist))
    {
        //sys_vgui(".x%x.c coords %s %d %d %d %d\n", x->x_glist, h->h_outlinetag,
        //    x1, y1, x2+h->h_dragx, y2+h->h_dragy);
911 912 913
    }
}

914 915 916 917 918 919 920 921 922 923 924
static void scalehandle_clickhook(t_scalehandle *h, t_floatarg f,
    t_floatarg xxx, t_floatarg yyy)
{
    h->h_offset_x=xxx;
    h->h_offset_y=yyy;
    h->h_clickfn(h,f);
}

static void scalehandle_motionhook(t_scalehandle *h,
    t_floatarg f1, t_floatarg f2)
{
925 926 927 928
    h->h_motionfn(h,f1,f2);
    // Now set the offset to the new mouse position
    h->h_offset_x = f1;
    h->h_offset_y = f2;
929 930
}

931 932 933 934 935 936 937 938
void iemgui__clickhook3(t_scalehandle *sh, int newstate) {
    if (!sh->h_dragon && newstate && sh->h_scale)
        scalehandle_click_scale(sh);
    else if (!sh->h_dragon && newstate && !sh->h_scale)
        scalehandle_click_label(sh);
    sh->h_dragon = newstate;
}

939 940 941 942 943
// function for updating of handles on iemgui objects
// we don't need glist_getcanvas() because handles are only
// drawn when object is selected on its canvas (instead of GOP)
static void scalehandle_check_and_redraw(t_iemgui *x)
{
Jonathan Wilkes's avatar
Jonathan Wilkes committed
944
    if (x->x_selected == x->x_glist)
945
        scalehandle_draw_select2(x);
946 947
}

948 949 950
//----------------------------------------------------------------
// IEMGUI refactor (by Mathieu)

951 952
void iemgui_tag_selected(t_iemgui *x) {
    t_canvas *canvas=glist_getcanvas(x->x_glist);
Jonathan Wilkes's avatar
Jonathan Wilkes committed
953
    if (x->x_selected)
954
        gui_vmess("gui_gobj_select", "xx", canvas, x);
955
    else
956
        gui_vmess("gui_gobj_deselect", "xx", canvas, x);
957 958
}

959
void iemgui_label_draw_new(t_iemgui *x) {
960
    char col[8];
961
    t_canvas *canvas=glist_getcanvas(x->x_glist);
962 963 964
    int x1=text_xpix(&x->x_obj, x->x_glist)+x->legacy_x;
    int y1=text_ypix(&x->x_obj, x->x_glist)+x->legacy_y;
    iemgui_getrect_legacy_label(x, &x1, &y1);
965
    sprintf(col, "#%6.6x", x->x_lcol);
966
    gui_vmess("gui_iemgui_label_new", "xxiissssi",
967 968
        canvas,
        x,
969 970 971 972
        x->x_ldx,
        x->x_ldy,
        col,
        x->x_lab != s_empty ? x->x_lab->s_name : "",
973 974 975
        iemgui_typeface(x),
        sys_fontweight,
        x->x_fontsize);
976
}
977

978 979
void iemgui_label_draw_move(t_iemgui *x)
{
980
    t_canvas *canvas=glist_getcanvas(x->x_glist);
981 982
    //int x1=text_xpix(&x->x_obj, x->x_glist)+x->legacy_x;
    //int y1=text_ypix(&x->x_obj, x->x_glist)+x->legacy_y;
983
    //iemgui_getrect_legacy_label(x, &x1, &y1);
984 985
    //sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",
    //    canvas, x, x1+x->x_ldx, y1+x->x_ldy);
986 987 988 989

    /* Note-- since we're not using x1/y1 above in the new GUI call,
       Ivica's legacy logic isn't affecting us. Quick fix below by
       just adding the legacy offsets... */
990
    gui_vmess("gui_iemgui_label_coords", "xxii",
991
        canvas,
992
        x,
993 994
        x->x_ldx + x->legacy_x,
        x->x_ldy + x->legacy_y);
995
}
996

997
void iemgui_label_draw_config(t_iemgui *x) {
998
    char col[8];
999
    t_canvas *canvas=glist_getcanvas(x->x_glist);
1000
    if (x->x_selected == canvas && x->x_glist == canvas)
1001
    {
1002
        gui_vmess("gui_iemgui_label_font", "xxssi",
1003 1004
            glist_getcanvas(x->x_glist),
            x,
1005 1006 1007
            iemgui_typeface(x),
            sys_fontweight,
            x->x_fontsize);
1008 1009 1010
        gui_vmess("gui_iemgui_label_set", "xxs",
            glist_getcanvas(x->x_glist),
            x,
1011 1012
            x->x_lab != s_empty ? x->x_lab->s_name: "");
        sprintf(col, "#%6.6x", x->x_lcol);
1013 1014 1015
        gui_vmess("gui_iemgui_label_color", "xxs",
            canvas,
            x,
1016 1017
            col);
    }
1018
    else
1019
    {
1020
        gui_vmess("gui_iemgui_label_font", "xxssi",
1021 1022
            glist_getcanvas(x->x_glist),
            x,
1023 1024 1025
            iemgui_typeface(x),
            sys_fontweight,
            x->x_fontsize);
1026 1027 1028
        gui_vmess("gui_iemgui_label_set", "xxs",
            glist_getcanvas(x->x_glist),
            x,
1029 1030
            x->x_lab != s_empty ? x->x_lab->s_name: "");
        sprintf(col, "#%6.6x", x->x_lcol);
1031 1032 1033
        gui_vmess("gui_iemgui_label_color", "xxs",
            canvas,
            x,
1034 1035
            col);
    }
1036
    if (x->x_selected == canvas && x->x_glist == canvas)
1037 1038
    {
        t_scalehandle *lh = (t_scalehandle *)(x->x_lhandle);
1039
        if (x->x_lab==s_empty)    
1040
            scalehandle_draw_erase(x->x_lhandle);
1041
        else if (lh->h_vis == 0)
1042
            scalehandle_draw_select(lh,x->x_ldx,x->x_ldy);
1043
    }
1044
}