g_all_guis.c 36.4 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
21
t_symbol *s_empty;

22
23
24
25
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
26
27
};

28
29
int iemgui_clip_size(int size) {return maxi(size,IEM_GUI_MINSIZE);}
int iemgui_clip_font(int size) {return maxi(size,IEM_FONT_MINSIZE);}
Miller Puckette's avatar
Miller Puckette committed
30

31
static int iemgui_modulo_color(int col)
Miller Puckette's avatar
Miller Puckette committed
32
{
33
    const int IEM_GUI_MAX_COLOR = 30;
34
35
36
    col %= IEM_GUI_MAX_COLOR;
    if (col<0) col += IEM_GUI_MAX_COLOR;
    return col;
Miller Puckette's avatar
Miller Puckette committed
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
}

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++)
    {
        if (*s1 == '$')
            *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++)
    {
        if (*s1 == '#')
            *s2 = '$';
        else if (!(*s2 = *s1))
            break;
    }
    return(gensym(buf));
}

69
void iemgui_verify_snd_ne_rcv(t_iemgui *x)
Miller Puckette's avatar
Miller Puckette committed
70
{
71
72
    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
73
74
}

75
t_symbol *iemgui_getfloatsym(t_atom *a)
Miller Puckette's avatar
Miller Puckette committed
76
{
77
78
79
80
81
    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
82
    }
83
84
85
86
87
88
    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
89
90
}

91
void iemgui_new_getnames(t_iemgui *x, int indx, t_atom *argv)
Miller Puckette's avatar
Miller Puckette committed
92
93
94
{
    if (argv)
    {
95
96
97
        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
98
    }
99
100
101
102
    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
103
104
}

105
106
107
108
/* 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
109
110
111
112
    int indx, t_symbol *fallback)
{
    if (!*symp)
    {
113
        t_binbuf *b = x->x_obj.ob_binbuf;
Miller Puckette's avatar
Miller Puckette committed
114
115
116
117
118
119
120
121
        if (binbuf_getnatom(b) > indx)
        {
            char buf[80];
            atom_string(binbuf_getvec(b) + indx, buf, 80);
            *symp = gensym(buf);
        }
        else if (fallback)
            *symp = fallback;
122
        else *symp = s_empty;
Miller Puckette's avatar
Miller Puckette committed
123
124
125
    }
}

126
/* get the unexpanded versions of the symbols; initialize them if necessary. */
127
void iemgui_all_sym2dollararg(t_iemgui *x, t_symbol **srlsym)
Miller Puckette's avatar
Miller Puckette committed
128
{
129
130
131
132
133
134
    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
135
136
}

137
138
139
static int col2save(int col) {
    return -1-(((0xfc0000 & col) >> 6)|((0xfc00 & col) >> 4)|((0xfc & col) >> 2));
}
140
void iemgui_all_col2save(t_iemgui *x, int *bflcol)
Miller Puckette's avatar
Miller Puckette committed
141
{
142
143
144
    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
145
146
}

147
148
static int colfromload(int col) {
    if(col)
Miller Puckette's avatar
Miller Puckette committed
149
    {
150
151
        col = -1-col;
        return ((col & 0x3f000) << 6)|((col & 0xfc0) << 4)|((col & 0x3f) << 2);
Miller Puckette's avatar
Miller Puckette committed
152
153
    }
    else
154
155
        return iemgui_color_hex[iemgui_modulo_color(col)];
}
156
void iemgui_all_colfromload(t_iemgui *x, int *bflcol)
157
{
158
159
160
    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
161
162
}

163
static int iemgui_compatible_col(int i)
Miller Puckette's avatar
Miller Puckette committed
164
165
{
    if(i >= 0)
166
167
        return(iemgui_color_hex[(iemgui_modulo_color(i))]);
    return((-1-i)&0xffffff);
Miller Puckette's avatar
Miller Puckette committed
168
169
170
171
172
173
174
175
176
}

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]);
}

177
void iemgui_send(t_iemgui *x, t_symbol *s)
Miller Puckette's avatar
Miller Puckette committed
178
179
{
    t_symbol *snd;
180
    if (s == &s_) s = s_empty; //tb: fix for empty label
181
182
183
    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
184
185

    snd = iemgui_raute2dollar(s);
186
187
188
    x->x_snd_unexpanded = snd;
    x->x_snd = snd = canvas_realizedollar(x->x_glist, snd);
    iemgui_verify_snd_ne_rcv(x);
189
    iemgui_draw_io(x, x->x_glist, oldsndrcvable);
Miller Puckette's avatar
Miller Puckette committed
190
191
}

192
void iemgui_receive(t_iemgui *x, t_symbol *s)
Miller Puckette's avatar
Miller Puckette committed
193
194
{
    t_symbol *rcv;
195
    if (s == &s_) s = s_empty; //tb: fix for empty label
196
197
198
    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
199
200

    rcv = iemgui_raute2dollar(s);
201
202
    x->x_rcv_unexpanded = rcv;
    rcv = canvas_realizedollar(x->x_glist, rcv);
203
    if(s!=s_empty)
Miller Puckette's avatar
Miller Puckette committed
204
    {
205
        if(rcv!=x->x_rcv)
Miller Puckette's avatar
Miller Puckette committed
206
        {
207
208
209
210
            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
211
212
        }
    }
213
    else if(s==s_empty && iemgui_has_rcv(x))
Miller Puckette's avatar
Miller Puckette committed
214
    {
215
216
        pd_unbind((t_pd *)x, x->x_rcv);
        x->x_rcv = rcv;
Miller Puckette's avatar
Miller Puckette committed
217
    }
218
    iemgui_verify_snd_ne_rcv(x);
219
    iemgui_draw_io(x, x->x_glist, oldsndrcvable);
Miller Puckette's avatar
Miller Puckette committed
220
221
}

222
void iemgui_label(t_iemgui *x, t_symbol *s)
Miller Puckette's avatar
Miller Puckette committed
223
{
224
225
226
227
    if (s == &s_) s = s_empty; //tb: fix for empty label
    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
228

229
    if(glist_isvisible(x->x_glist))
230
    {
Miller Puckette's avatar
Miller Puckette committed
231
        sys_vgui(".x%lx.c itemconfigure %lxLABEL -text {%s} \n",
232
233
234
            glist_getcanvas(x->x_glist), x,
            s!=s_empty?x->x_lab->s_name:"");
        iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_CONFIG);
235
    }
Miller Puckette's avatar
Miller Puckette committed
236
237
}

238
void iemgui_label_pos(t_iemgui *x, t_symbol *s, int ac, t_atom *av)
Miller Puckette's avatar
Miller Puckette committed
239
{
240
241
    x->x_ldx = atom_getintarg(0, ac, av);
    x->x_ldy = atom_getintarg(1, ac, av);
242
    if(glist_isvisible(x->x_glist))
243
244
    {
        sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",
245
246
247
248
            glist_getcanvas(x->x_glist), x,
            text_xpix((t_object *)x,x->x_glist)+x->x_ldx,
            text_ypix((t_object *)x,x->x_glist)+x->x_ldy);
        iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_CONFIG);
249
    }
Miller Puckette's avatar
Miller Puckette committed
250
251
}

252
void iemgui_label_font(t_iemgui *x, t_symbol *s, int ac, t_atom *av)
Miller Puckette's avatar
Miller Puckette committed
253
{
254
    int f = atom_getintarg(0, ac, av);
255
256
    if (f<0 || f>2) f=0;
    x->x_font_style = f;
257
    x->x_fontsize = maxi(atom_getintarg(1, ac, av),4);
258
    if(glist_isvisible(x->x_glist))
259
    {
260
        sys_vgui(".x%lx.c itemconfigure %lxLABEL -font %s\n",
261
262
263
            glist_getcanvas(x->x_glist), x, iemgui_font(x), 
            x->x_fontsize, sys_fontweight);
            iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_CONFIG);
264
    }
265
266
267
268
269
270
}

//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

271
272
273
274
275
276
// 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;

277
278
279
280
281
282
283
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);
    if (!gop_redraw)
    {
        //fprintf(stderr,"ignoring label\n");
284
        return;
285
286
287
    }

    t_float width_multiplier;
288
    int label_length;
289
290
291
292
    int label_x1;
    int label_y1;
    int label_x2;
    int label_y2;
293
    int actual_fontsize; //seems tk does its own thing when rendering
294
295
296
297
    int actual_height;

    if (x->gl_isgraph && !glist_istoplevel(x))
    {
298
        if (x_gui.x_lab!=s_empty)
299
        {
300
            switch(x_gui.x_font_style)
301
            {
302
303
304
                case 1:  width_multiplier = 0.83333; break;
                case 2:  width_multiplier = 0.735;   break;
                default: width_multiplier = 1.0;     break;
305
            }
306
            actual_fontsize = x_gui.x_fontsize;
307
            actual_height = actual_fontsize;
308
            //exceptions
309
            if (x_gui.x_font_style == 0 &&
310
311
312
313
314
315
316
                (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;
            }
317
            else if (x_gui.x_font_style == 1 && actual_fontsize >= 5 &&
318
319
                actual_fontsize < 13 && actual_fontsize % 2 == 1)
                actual_fontsize += 1;
320
            else if (x_gui.x_font_style == 2 && actual_fontsize >= 5 &&
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
                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
            //fprintf(stderr,"%f %d %d\n", width_multiplier,
337
            //    label_length, x_gui.x_font_style);
338
339
340
341
342
343
344
345
346
347
348
349
350
351
            //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);
        }
    }
352
353
}

354
void iemgui_shouldvis(t_iemgui *x, int mode)
355
{
356
    gop_redraw = 1;
357
    if(gobj_shouldvis((t_gobj *)x, x->x_glist))
358
    {
359
        if (!x->x_vis)
360
361
        {
            //fprintf(stderr,"draw new %d\n", mode);
362
            iemgui_draw_new(x, x->x_glist);
363
364
365
            canvas_fixlinesfor(glist_getcanvas(x->x_glist), (t_text*)x);
            x->x_vis = 1;
            if (x->x_glist != glist_getcanvas(x->x_glist))
366
367
368
369
            {
                /* 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 */
370
371
                t_canvas *canvas = glist_getcanvas(x->x_glist);
                t_gobj *y = (t_gobj *)x->x_glist;
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
                gobj_vis(y, canvas, 0);
                gobj_vis(y, canvas, 1);
                // reorder it visually
                glist_redraw(canvas);

                /*
                    // 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)
                {
                    fprintf(stderr,"not bottom\n");
                    while (yy && yy->g_next != y)
                    {
                        fprintf(stderr,"+\n");
                        yy = yy->g_next;
                    }
                    // now we have yy which is right before our y graph
                    t_object *ob = NULL;
                    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));
405
                        //canvas_raise_all_cords(canvas);
406
                    }
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
                    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);
                */
            }
        }
426
427
428
        //fprintf(stderr,"draw move x->x_w=%d\n", x->x_w);
        x->x_draw(x, x->x_glist, mode);
        canvas_fixlinesfor(glist_getcanvas(x->x_glist), (t_text*)x);
429
    }
430
    else if (x->x_vis)
431
432
    {
        //fprintf(stderr,"draw erase %d\n", mode);
433
        iemgui_draw_erase(x, x->x_glist);
434
        x->x_vis = 0;
435
436
    }
    gop_redraw = 0;
Miller Puckette's avatar
Miller Puckette committed
437
438
}

439
void iemgui_size(t_iemgui *x)
Miller Puckette's avatar
Miller Puckette committed
440
{
441
442
    if(glist_isvisible(x->x_glist))
        iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_MOVE);
Miller Puckette's avatar
Miller Puckette committed
443
444
}

445
void iemgui_delta(t_iemgui *x, t_symbol *s, int ac, t_atom *av)
Miller Puckette's avatar
Miller Puckette committed
446
{
447
448
    x->x_obj.te_xpix += atom_getintarg(0, ac, av);
    x->x_obj.te_ypix += atom_getintarg(1, ac, av);
449
450
    if(glist_isvisible(x->x_glist))
        iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_MOVE);
Miller Puckette's avatar
Miller Puckette committed
451
452
}

453
void iemgui_pos(t_iemgui *x, t_symbol *s, int ac, t_atom *av)
Miller Puckette's avatar
Miller Puckette committed
454
{
455
456
    x->x_obj.te_xpix = atom_getintarg(0, ac, av);
    x->x_obj.te_ypix = atom_getintarg(1, ac, av);
457
458
    if(glist_isvisible(x->x_glist))
        iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_MOVE);
Miller Puckette's avatar
Miller Puckette committed
459
460
}

461
void iemgui_color(t_iemgui *x, t_symbol *s, int ac, t_atom *av)
Miller Puckette's avatar
Miller Puckette committed
462
{
463
    x->x_bcol = iemgui_compatible_col(atom_getintarg(0, ac, av));
Miller Puckette's avatar
Miller Puckette committed
464
465
    if(ac > 2)
    {
466
467
        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
468
469
    }
    else
470
471
472
        x->x_lcol = iemgui_compatible_col(atom_getintarg(1, ac, av));
    if(glist_isvisible(x->x_glist))
        x->x_draw(x, x->x_glist, IEM_GUI_DRAW_MODE_CONFIG);
Miller Puckette's avatar
Miller Puckette committed
473
474
475
476
}

void iemgui_displace(t_gobj *z, t_glist *glist, int dx, int dy)
{
477
478
479
480
    t_iemgui *x = (t_iemgui *)z;
    x->x_obj.te_xpix += dx;
    x->x_obj.te_ypix += dy;
    iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_MOVE);
Miller Puckette's avatar
Miller Puckette committed
481
482
}

483
484
void iemgui_displace_withtag(t_gobj *z, t_glist *glist, int dx, int dy)
{
485
486
487
    t_iemgui *x = (t_iemgui *)z;
    x->x_obj.te_xpix += dx;
    x->x_obj.te_ypix += dy;
488
    //x->x_gui.x_draw((void *)z, glist, IEM_GUI_DRAW_MODE_MOVE);
489
490
491
492
    canvas_fixlinesfor(glist_getcanvas(glist), (t_text *)z);
}


Miller Puckette's avatar
Miller Puckette committed
493
494
void iemgui_select(t_gobj *z, t_glist *glist, int selected)
{
495
    t_iemgui *x = (t_iemgui *)z;
496
    t_canvas *canvas=glist_getcanvas(glist);
497
498
499
500
    if (selected)
        x->x_selected = canvas;
    else
        x->x_selected = NULL;
501
    char fcol[8]; sprintf(fcol,"#%6.6x", x->x_fcol);
502
    sys_vgui(".x%lx.c itemconfigure {x%lx&&border} -stroke %s\n", canvas, x,
503
        x->x_selected && x->x_glist == canvas ? selection_color : fcol);
504
    x->x_draw((void *)z, glist, IEM_GUI_DRAW_MODE_SELECT);
505
506
507
    scalehandle_draw(x,glist);
    iemgui_label_draw_select(x,canvas);
    iemgui_tag_selected(x,canvas);
Miller Puckette's avatar
Miller Puckette committed
508
509
510
511
512
513
514
515
516
}

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)
{
517
    t_iemgui *x = (t_iemgui *)z;
518
519
520
    if (gobj_shouldvis(z, glist))
    {
        if (vis)
521
            iemgui_draw_new(x, glist);
522
523
        else
        {
524
            iemgui_draw_erase(x, x->x_glist);
525
526
            sys_unqueuegui(z);
        }
527
        x->x_vis = vis;
528
    }
Miller Puckette's avatar
Miller Puckette committed
529
530
}

531
void iemgui_save(t_iemgui *x, t_symbol **srl, int *bflcol)
Miller Puckette's avatar
Miller Puckette committed
532
{
533
534
535
536
537
538
539
    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
540
541
}

542
void iemgui_properties(t_iemgui *x, t_symbol **srl)
Miller Puckette's avatar
Miller Puckette committed
543
{
544
545
546
547
548
549
550
    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
551
552
}

553
int iemgui_dialog(t_iemgui *x, int argc, t_atom *argv)
Miller Puckette's avatar
Miller Puckette committed
554
{
555
    t_symbol *srl[3];
556
557
558
559
560
561
562
563
564
565
566
567
    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;
568
569
    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
570
    iemgui_all_raute2dollar(srl);
571
572
573
574
    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
575
    {
576
577
578
579
        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
580
    }
581
582
    x->x_snd = srl[0];
    x->x_lab = srl[2];
583
    if(f<0 || f>2) f=0;
584
585
586
    x->x_font_style = f;
    iemgui_verify_snd_ne_rcv(x);
    canvas_dirty(x->x_glist, 1);
587
    return oldsndrcvable;
Miller Puckette's avatar
Miller Puckette committed
588
589
}

590
void iem_inttosymargs(t_iemgui *x, int n)
Miller Puckette's avatar
Miller Puckette committed
591
{
592
593
594
    x->x_loadinit = (n >>  0);
    x->x_locked = 0;
    x->x_reverse = 0;
Miller Puckette's avatar
Miller Puckette committed
595
596
}

597
int iem_symargstoint(t_iemgui *x)
Miller Puckette's avatar
Miller Puckette committed
598
{
599
    return ((x->x_loadinit & 1) <<  0);
Miller Puckette's avatar
Miller Puckette committed
600
601
}

602
void iem_inttofstyle(t_iemgui *x, int n)
Miller Puckette's avatar
Miller Puckette committed
603
{
604
    x->x_font_style = (n >> 0);
605
    x->x_selected = NULL;
606
607
608
609
610
611
    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
612
{
613
    return ((x->x_font_style << 0) & 63);
Miller Puckette's avatar
Miller Puckette committed
614
}
615

616
//----------------------------------------------------------------
617
// SCALEHANDLE COMMON CODE (by Mathieu, refactored from existing code)
618

619
620
extern int gfxstub_haveproperties(void *key);

621
622
623
624
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;}
625

626
627
628
629
630
631
632
633
634
635
636
637
638
// in all 20 cases :
// [bng], [tgl], [hradio], [vradio], [hsl], [vsl], [cnv], [nbx], [vu]
// for both scale & label, plus canvas' scale & move.
void scalehandle_bind(t_scalehandle *h) {
    sys_vgui("bind %s <Button> {pd [concat %s _click 1 %%x %%y \\;]}\n",
        h->h_pathname, h->h_bindsym->s_name);
    sys_vgui("bind %s <ButtonRelease> {pd [concat %s _click 0 0 0 \\;]}\n",
        h->h_pathname, h->h_bindsym->s_name);
    sys_vgui("bind %s <Motion> {pd [concat %s _motion %%x %%y \\;]}\n",
        h->h_pathname, h->h_bindsym->s_name);
}

// in 18 cases only, because canvas does not fit the pattern below.
639
640
// 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)
641
void scalehandle_draw_select(t_scalehandle *h, t_glist *canvas, int px, int py) {
642
    char tags[128]; // BNG may need up to 100 chars in 64-bit mode, for example
643
    t_iemgui *x = (t_iemgui *)h->h_master;
644

645
646
647
648
649
650
651
652
653
654
655
    //int px,py;
    //t_class *c = pd_class((t_pd *)x);
    //if (h->h_scale) {
    //    int x1,y1,x2,y2;
    //    c->c_wb->w_getrectfn((t_gobj *)x,canvas,&x1,&y1,&x2,&y2);
    //    px=x2-x1; py=y2-y1;
    //} else if (c==canvas_class) {  
    //} else {
    //    px=x->x_ldx; py=x->x_ldy;
    //}

656
657
658
659
    const char *cursor = h->h_scale ? "bottom_right_corner" : "crosshair";
    int sx = h->h_scale ? SCALEHANDLE_WIDTH  : LABELHANDLE_WIDTH;
    int sy = h->h_scale ? SCALEHANDLE_HEIGHT : LABELHANDLE_HEIGHT;

660
661
    scalehandle_draw_erase(h,canvas);

662
663
664
665
    if (!h->h_vis) {
        sys_vgui("canvas %s -width %d -height %d -bg $pd_colors(selection) -bd 0 "
            "-cursor %s\n", h->h_pathname, sx, sy, cursor);
        if (h->h_scale) {
666
            sprintf(tags,"x%lx %lxSCALE iemgui selected", (long)x,(long)x);
667
        } else {
668
            sprintf(tags,"x%lx %lx%s iemgui selected", (long)x,
669
670
671
672
673
674
675
676
                (long)x,pd_class((t_pd *)x)==canvas_class?"MOVE":"LABELH");
        }
        sys_vgui(".x%x.c create window %d %d -anchor nw -width %d -height %d "
            "-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);
        h->h_vis = 1;
677
    /* not yet (this is not supported by current implementation)
678
    } else {
679
680
        sys_vgui(".x%x.c coords %s %d %d\n", canvas, h->h_pathname,
            x->x_obj.te_xpix+px-sx, x->x_obj.te_ypix+py-sy);
681
        sys_vgui("raise %s\n", h->h_pathname); */
682
683
684
    }
}

685
686
extern t_class *my_canvas_class;

687
688
void scalehandle_draw_select2(t_iemgui *x, t_glist *canvas) {
    t_class *c = pd_class((t_pd *)x);
689
690
691
692
693
694
695
696
697
698
    int sx,sy;
    if (c==my_canvas_class) {
        t_my_canvas *y = (t_my_canvas *)x;
        sx=y->x_vis_w; sy=y->x_vis_h;
    } else {
        int x1,y1,x2,y2;
        c->c_wb->w_getrectfn((t_gobj *)x,canvas,&x1,&y1,&x2,&y2);
        sx=x2-x1; sy=y2-y1;
    }
    scalehandle_draw_select(x->x_handle,canvas,sx-1,sy-1);
699
    if (x->x_lab!=s_empty)
700
        scalehandle_draw_select(x->x_lhandle,canvas,x->x_ldx,x->x_ldy);
701
702
}

703
void scalehandle_draw_erase(t_scalehandle *h, t_glist *canvas) {
704
705
    if (!h->h_vis) return;
    sys_vgui("destroy %s\n", h->h_pathname);
706
707
708
    sys_vgui(".x%lx.c delete %lx%s\n", canvas, h->h_master,
        h->h_scale ? "SCALE" : pd_class((t_pd *)h->h_master)==canvas_class?"MOVE":"LABELH");
    h->h_vis = 0;
709
710
711
}

void scalehandle_draw_erase2(t_iemgui *x, t_glist *canvas) {
712
713
    t_scalehandle *sh = (t_scalehandle *)(x->x_handle);
    t_scalehandle *lh = (t_scalehandle *)(x->x_lhandle);
714
715
716
717
    if (sh->h_vis) scalehandle_draw_erase(sh,canvas);
    if (lh->h_vis) scalehandle_draw_erase(lh,canvas);
}

718
719
void scalehandle_draw(t_iemgui *x, t_glist *glist) {
    if (x->x_glist == glist_getcanvas(glist)) {
720
        if(x->x_selected == x->x_glist) scalehandle_draw_select2(x,glist);
721
        else scalehandle_draw_erase2(x,glist);
722
    }
723
724
725
726
727
728
729
730
731
732
733
}

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;
734
735
    //h->h_offset_x = 0; // unused (maybe keep for later)
    //h->h_offset_y = 0; // unused (maybe keep for later)
736
    h->h_vis = 0;
737
    sprintf(h->h_pathname, ".x%lx.h%lx", (t_int)x->x_glist, (t_int)h);
738
739
740
741
742
743
    return h;
}

void scalehandle_free(t_scalehandle *h) {
    pd_unbind((t_pd *)h, h->h_bindsym);
    pd_free((t_pd *)h);
744
}
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760

void properties_set_field_int(long props, const char *gui_field, int value) {
    sys_vgui(".gfxstub%lx.%s delete 0 end\n", props, gui_field);
    sys_vgui(".gfxstub%lx.%s insert 0 %d\n", props, gui_field, value);
};

void scalehandle_dragon_label(t_scalehandle *h, float f1, float f2) {
    if (h->h_dragon && !h->h_scale)
    {
        t_iemgui *x = (t_iemgui *)(h->h_master);
        int dx = (int)f1, dy = (int)f2;
        h->h_dragx = dx;
        h->h_dragy = dy;
        int properties = gfxstub_haveproperties((void *)x);
        if (properties)
        {
761
762
            int new_x = x->x_ldx + h->h_dragx;
            int new_y = x->x_ldy + h->h_dragy;
763
764
765
766
767
768
769
770
            properties_set_field_int(properties,"label.xy.x_entry",new_x);
            properties_set_field_int(properties,"label.xy.y_entry",new_y);
        }
        if (glist_isvisible(x->x_glist))
        {
            int xpos=text_xpix(&x->x_obj, x->x_glist);
            int ypos=text_ypix(&x->x_obj, x->x_glist);
            t_canvas *canvas=glist_getcanvas(x->x_glist);
771
772
773
            sys_vgui(".x%lx.c coords %lxLABEL %d %d\n", canvas, x,
                xpos+x->x_ldx + h->h_dragx,
                ypos+x->x_ldy + h->h_dragy);
774
775
776
        }
    }
}
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850

void scalehandle_unclick_label(t_scalehandle *h) {
    t_iemgui *x = (t_iemgui *)h->h_master;
    canvas_apply_setundo(x->x_glist, (t_gobj *)x);
    if (h->h_dragx || h->h_dragy)
    {
        x->x_ldx += h->h_dragx;
        x->x_ldy += h->h_dragy;
        canvas_dirty(x->x_glist, 1);
    }
    if (glist_isvisible(x->x_glist))
    {
        iemgui_select((t_gobj *)x, x->x_glist, 1);
        canvas_fixlinesfor(x->x_glist, (t_text *)x);
        sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", x->x_glist);
    }
}

void scalehandle_click_label(t_scalehandle *h) {
    t_iemgui *x = (t_iemgui *)h->h_master;
    if (glist_isvisible(x->x_glist))
    {
        sys_vgui("lower %s\n", h->h_pathname);
        t_scalehandle *othersh = x->x_handle;
        sys_vgui("lower .x%lx.h%lx\n",
            (t_int)glist_getcanvas(x->x_glist), (t_int)othersh);
    }
    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);
    //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);
    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);
    }
    h->h_dragx = 0;
    h->h_dragy = 0;
}

void scalehandle_unclick_scale(t_scalehandle *h) {
    t_iemgui *x = (t_iemgui *)h->h_master;
    sys_vgui(".x%x.c delete %s\n", x->x_glist, h->h_outlinetag);
    iemgui_select((t_gobj *)x, x->x_glist, 1);
    canvas_fixlinesfor(x->x_glist, (t_text *)x);
    sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", x->x_glist);
}

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);
    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);
    }
}

851
852
853
854
855
856
857
858
859
860
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 == 0 && !sh->h_scale)
        scalehandle_unclick_label(sh);
    else if (!sh->h_dragon && newstate && !sh->h_scale)
        scalehandle_click_label(sh);
    sh->h_dragon = newstate;
}

861
862
863
//----------------------------------------------------------------
// IEMGUI refactor (by Mathieu)

864
void iemgui_tag_selected(t_iemgui *x, t_glist *canvas) {
865
    if(x->x_selected)
866
        sys_vgui(".x%lx.c addtag selected withtag x%lx\n", canvas, x);
867
    else
868
        sys_vgui(".x%lx.c dtag x%lx selected\n", canvas, x);
869
870
}

871
872
873
void iemgui_label_draw_new(t_iemgui *x, t_glist *canvas) {
    int x1=text_xpix(&x->x_obj, x->x_glist);
    int y1=text_ypix(&x->x_obj, x->x_glist);
874
    sys_vgui(".x%lx.c create text %d %d -text {%s} -anchor w "
875
             "-font %s -fill #%6.6x -tags {%lxLABEL x%lx text iemgui}\n",
876
         canvas, x1+x->x_ldx, y1+x->x_ldy,
877
         x->x_lab!=s_empty?x->x_lab->s_name:"",
878
         iemgui_font(x), x->x_lcol, x, x);
879
}
880

881
882
883
void iemgui_label_draw_move(t_iemgui *x, t_glist *canvas) {
    int x1=text_xpix(&x->x_obj, x->x_glist);
    int y1=text_ypix(&x->x_obj, x->x_glist);
884
    sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",
885
        canvas, x, x1+x->x_ldx, y1+x->x_ldy);
886
}
887

888
void iemgui_label_draw_config(t_iemgui *x, t_glist *canvas) {
889
    if (x->x_selected == canvas && x->x_glist == canvas)
890
        sys_vgui(".x%lx.c itemconfigure %lxLABEL -font %s "
891
                 "-fill $pd_colors(selection) -text {%s} \n",
892
             canvas, x, iemgui_font(x), 
893
             x->x_lab!=s_empty?x->x_lab->s_name:"");
894
    else
895
        sys_vgui(".x%lx.c itemconfigure %lxLABEL -font %s "
896
                 "-fill #%6.6x -text {%s} \n",
897
             canvas, x, iemgui_font(x),
898
             x->x_lcol, x->x_lab!=s_empty?x->x_lab->s_name:"");
899
    if (x->x_selected)
900
901
    {
        t_scalehandle *lh = (t_scalehandle *)(x->x_lhandle);
902
903
904
905
        if (x->x_lab==s_empty)    
            scalehandle_draw_erase((t_scalehandle *)(x->x_lhandle),canvas);
        else if (lh->h_vis == 0)
            scalehandle_draw_select(lh,canvas,x->x_ldx,x->x_ldy);
906
    }
907
}
908

909
void iemgui_label_draw_select(t_iemgui *x, t_glist *canvas) {
910
    if (x->x_selected == canvas && x->x_glist == canvas)
911
912
913
914
915
916
917
        sys_vgui(".x%lx.c itemconfigure %lxLABEL "
            "-fill $pd_colors(selection)\n", canvas, x);
    else
        sys_vgui(".x%lx.c itemconfigure %lxLABEL -fill #%6.6x\n",
            canvas, x, x->x_lcol);
}

918
extern t_class *vu_class;
919
920
921
922
void iemgui_draw_io(t_iemgui *x, t_glist *glist, int old_sr_flags)
{
    t_canvas *canvas=glist_getcanvas(glist);
    if (x->x_glist != canvas) return; // is gop
923
924
925
926
927
    t_class *c = pd_class((t_pd *)x);

    if (!(old_sr_flags&4) && (!glist_isvisible(canvas) || !(canvas == x->x_glist))) {
        return;
    }
928
    if (c==my_canvas_class) return;
929
930
931
932

    int x1,y1,x2,y2;
    c->c_wb->w_getrectfn((t_gobj *)x,canvas,&x1,&y1,&x2,&y2);

933
934
    int i, n = c==vu_class ? 2 : 1, k=(x2-x1)-IOWIDTH;

935
936
    int a=old_sr_flags&IEM_GUI_OLD_SND_FLAG;
    int b=x->x_snd!=s_empty;
937
    //fprintf(stderr,"%lx SND: old_sr_flags=%d SND_FLAG=%d || OUTCOME: OLD_SND_FLAG=%d not_empty=%d\n", (t_int)x, old_sr_flags, IEM_GUI_OLD_SND_FLAG, a, b);
938
    
939
    if(a && !b) for (i=0; i<n; i++)
940
941
        sys_vgui(".x%lx.c create prect %d %d %d %d "
                 "-stroke $pd_colors(iemgui_nlet) "
942
                 "-tags {x%lxo%d x%lx outlet iemgui}\n",
943
             canvas, x1+i*k, y2-1, x1+i*k + IOWIDTH, y2,
944
             x, i, x);
945
    if(!a && b) for (i=0; i<n; i++)
946
        sys_vgui(".x%lx.c delete x%lxo%d\n", canvas, x, i);
947
948
949

    a=old_sr_flags&IEM_GUI_OLD_RCV_FLAG;
    b=x->x_rcv!=s_empty;
950
    //fprintf(stderr,"%lx RCV: old_sr_flags=%d RCV_FLAG=%d || OUTCOME: OLD_RCV_FLAG=%d not_empty=%d\n", (t_int)x, old_sr_flags, IEM_GUI_OLD_RCV_FLAG, a, b);
951
    if(a && !b) for (i=0; i<n; i++)
952
953
        sys_vgui(".x%lx.c create prect %d %d %d %d "
                 "-stroke $pd_colors(iemgui_nlet) "
954
                 "-tags {x%lxi%d x%lx inlet iemgui}\n",
955
             canvas, x1+i*k, y1, x1+i*k + IOWIDTH, y1+1,
956
             x, i, x);
957
    if(!a && b) for (i=0; i<n; i++)
958
        sys_vgui(".x%lx.c delete x%lxi%d\n", canvas, x, i);
959
960
}

961
void iemgui_io_draw_move(t_iemgui *x, t_glist *canvas) {
962
963
964
965
966
    t_class *c = pd_class((t_pd *)x);
    int x1,y1,x2,y2;
    c->c_wb->w_getrectfn((t_gobj *)x,canvas,&x1,&y1,&x2,&y2);
    int i, n = c==vu_class ? 2 : 1, k=(x2-x1)-IOWIDTH;
    if(!iemgui_has_snd(x) && canvas == x->x_glist) for (i=0; i<n; i++)
967
968
        sys_vgui(".x%lx.c coords x%lxo%d %d %d %d %d\n",
            canvas, x, i, x1+i*k, y2-1, x1+i*k+IOWIDTH, y2);
969
    if(!iemgui_has_rcv(x) && canvas == x->x_glist) for (i=0; i<n; i++)
970
971
        sys_vgui(".x%lx.c coords x%lxi%d %d %d %d %d\n",
            canvas, x, i, x1+i*k, y1, x1+i*k+IOWIDTH, y1+1);
972
973
}

974
void iemgui_base_draw_new(t_iemgui *x, t_glist *canvas) {
975
    t_class *c = pd_class((t_pd *)x);
976
    int x1,y1,x2,y2,gr=gop_redraw; gop_redraw=0;
977
    c->c_wb->w_getrectfn((t_gobj *)x,x->x_glist,&x1,&y1,&x2,&y2);
978
    gop_redraw=gr;
979
980
    sys_vgui(".x%lx.c create prect %d %d %d %d "
             "-stroke $pd_colors(iemgui_border) -fill #%6.6x "
981
982
             "-tags {%lxBASE x%lx text iemgui border}\n",
         canvas, x1,y1,x2,y2, x->x_bcol, x, x);
983
984
}

985
void iemgui_base_draw_move(t_iemgui *x, t_glist *canvas) {
986
    t_class *c = pd_class((t_pd *)x);
987
    int x1,y1,x2,y2,gr=gop_redraw; gop_redraw=0;
988
    c->c_wb->w_getrectfn((t_gobj *)x,x->x_glist,&x1,&y1,&x2,&y2);
989
    gop_redraw=gr;
990
991
992
993
994
995
996
997
    sys_vgui(".x%lx.c coords %lxBASE %d %d %d %d\n", canvas, x, x1, y1, x2, y2);
}

void iemgui_base_draw_config(t_iemgui *x, t_glist *canvas) {
    char fcol[8]; sprintf(fcol,"#%6.6x", x->x_fcol);
    sys_vgui(".x%lx.c itemconfigure %lxBASE -fill #%6.6x\n", canvas, x, x->x_bcol);
}

998
999
1000
void iemgui_draw_new(t_iemgui *x, t_glist *glist) {
    x->x_draw(x, x->x_glist, IEM_GUI_DRAW_MODE_NEW);
    t_canvas *canvas=glist_getcanvas(glist);
1001
    iemgui_label_draw_new(x,canvas);
1002
    iemgui_draw_io(x,glist,7);
1003
    canvas_raise_all_cords(glist_getcanvas(x->x_glist)); // used to be inside x_draw
1004
1005
}
void iemgui_draw_erase(t_iemgui *x, t_glist *glist) {
1006
    t_canvas