g_all_guis.c 36.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
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

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

833
834
835
// 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
836
837
838
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);
839
    iemgui_io_draw_move(x, x->x_glist);
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
    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);
    }
}

855
856
857
858
859
860
861
862
863
864
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;
}

865
866
867
//----------------------------------------------------------------
// IEMGUI refactor (by Mathieu)

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

875
876
877
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);
878
    sys_vgui(".x%lx.c create text %d %d -text {%s} -anchor w "
879
             "-font %s -fill #%6.6x -tags {%lxLABEL x%lx text iemgui}\n",
880
         canvas, x1+x->x_ldx, y1+x->x_ldy,
881
         x->x_lab!=s_empty?x->x_lab->s_name:"",
882
         iemgui_font(x), x->x_lcol, x, x);
883
}
884

885
886
887
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);
888
    sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",
889
        canvas, x, x1+x->x_ldx, y1+x->x_ldy);
890
}
891

892
void iemgui_label_draw_config(t_iemgui *x, t_glist *canvas) {
893
    if (x->x_selected == canvas && x->x_glist == canvas)
894
        sys_vgui(".x%lx.c itemconfigure %lxLABEL -font %s "
895
                 "-fill $pd_colors(selection) -text {%s} \n",
896
             canvas, x, iemgui_font(x), 
897
             x->x_lab!=s_empty?x->x_lab->s_name:"");
898
    else
899
        sys_vgui(".x%lx.c itemconfigure %lxLABEL -font %s "
900
                 "-fill #%6.6x -text {%s} \n",
901
             canvas, x, iemgui_font(x),
902
             x->x_lcol, x->x_lab!=s_empty?x->x_lab->s_name:"");
903
    if (x->x_selected)
904
905
    {
        t_scalehandle *lh = (t_scalehandle *)(x->x_lhandle);
906
907
908
909
        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);
910
    }
911
}
912

913
void iemgui_label_draw_select(t_iemgui *x, t_glist *canvas) {
914
    if (x->x_selected == canvas && x->x_glist == canvas)
915
916
917
918
919
920
921
        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);
}

922
extern t_class *vu_class;
923
924
925
926
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
927
928
929
930
931
    t_class *c = pd_class((t_pd *)x);

    if (!(old_sr_flags&4) && (!glist_isvisible(canvas) || !(canvas == x->x_glist))) {
        return;
    }
932
    if (c==my_canvas_class) return;
933
934
935
936

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

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

939
940
    int a=old_sr_flags&IEM_GUI_OLD_SND_FLAG;
    int b=x->x_snd!=s_empty;
941
    //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);
942
    
943
    if(a && !b) for (i=0; i<n; i++)
944
945
        sys_vgui(".x%lx.c create prect %d %d %d %d "
                 "-stroke $pd_colors(iemgui_nlet) "
946
                 "-tags {x%lxo%d x%lx outlet iemgui}\n",
947
             canvas, x1+i*k, y2-1, x1+i*k + IOWIDTH, y2,
948
             x, i, x);
949
    if(!a && b) for (i=0; i<n; i++)
950
        sys_vgui(".x%lx.c delete x%lxo%d\n", canvas, x, i);
951
952
953

    a=old_sr_flags&IEM_GUI_OLD_RCV_FLAG;
    b=x->x_rcv!=s_empty;
954
    //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);
955
    if(a && !b) for (i=0; i<n; i++)
956
957
        sys_vgui(".x%lx.c create prect %d %d %d %d "
                 "-stroke $pd_colors(iemgui_nlet) "
958
                 "-tags {x%lxi%d x%lx inlet iemgui}\n",
959
             canvas, x1+i*k, y1, x1+i*k + IOWIDTH, y1+1,
960
             x, i, x);
961
    if(!a && b) for (i=0; i<n; i++)
962
        sys_vgui(".x%lx.c delete x%lxi%d\n", canvas, x, i);
963
964
}

965
void iemgui_io_draw_move(t_iemgui *x, t_glist *canvas) {
966
967
968
969
970
    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++)
971
972
        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);
973
    if(!iemgui_has_rcv(x) && canvas == x->x_glist) for (i=0; i<n; i++)
974
975
        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);
976
977
}

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

989
void iemgui_base_draw_move(t_iemgui *x, t_glist *canvas) {
990
    t_class *c = pd_class((t_pd *)x);
991
    int x1,y1,x2,y2,gr=gop_redraw; gop_redraw=0;
992
    c->c_wb->w_getrectfn((t_gobj *)x,x->x_glist,&x1,&y1,&x2,&y2);
993
    gop_redraw=gr;
994
995
996
997
998
999
1000
1001
    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);
}

1002
1003
1004
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);
1005
    iemgui_label_draw_new(x,canvas);