Newer
Older
/* 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 */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include "m_pd.h"
#include "g_canvas.h"
Mathieu L Bouchard
committed
t_symbol *s_empty;
Mathieu L Bouchard
committed
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
Mathieu L Bouchard
committed
int iemgui_clip_size(int size) {return maxi(size,IEM_GUI_MINSIZE);}
int iemgui_clip_font(int size) {return maxi(size,IEM_FONT_MINSIZE);}
static void scalehandle_check_and_redraw(t_iemgui *x);
Mathieu L Bouchard
committed
static int iemgui_modulo_color(int col)
const int IEM_GUI_MAX_COLOR = 30;
Mathieu L Bouchard
committed
col %= IEM_GUI_MAX_COLOR;
if (col<0) col += IEM_GUI_MAX_COLOR;
return col;
}
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));
}
Mathieu L Bouchard
committed
void iemgui_verify_snd_ne_rcv(t_iemgui *x)
Mathieu L Bouchard
committed
x->x_put_in2out =
!(iemgui_has_snd(x) && iemgui_has_rcv(x) && x->x_snd==x->x_rcv);
Mathieu L Bouchard
committed
t_symbol *iemgui_getfloatsym(t_atom *a)
Mathieu L Bouchard
committed
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);
Mathieu L Bouchard
committed
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;
Mathieu L Bouchard
committed
void iemgui_new_getnames(t_iemgui *x, int indx, t_atom *argv)
Mathieu L Bouchard
committed
x->x_snd = iemgui_getfloatsym(argv+indx+0);
x->x_rcv = iemgui_getfloatsym(argv+indx+1);
x->x_lab = iemgui_getfloatsym(argv+indx+2);
Mathieu L Bouchard
committed
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;
Mathieu L Bouchard
committed
/* 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,
int indx, t_symbol *fallback)
{
if (!*symp)
{
Mathieu L Bouchard
committed
t_binbuf *b = x->x_obj.ob_binbuf;
if (binbuf_getnatom(b) > indx)
{
char buf[80];
atom_string(binbuf_getvec(b) + indx, buf, 80);
*symp = gensym(buf);
}
else if (fallback)
*symp = fallback;
Mathieu L Bouchard
committed
else *symp = s_empty;
Mathieu L Bouchard
committed
/* get the unexpanded versions of the symbols; initialize them if necessary. */
Mathieu L Bouchard
committed
void iemgui_all_sym2dollararg(t_iemgui *x, t_symbol **srlsym)
Mathieu L Bouchard
committed
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;
Mathieu L Bouchard
committed
static int col2save(int col) {
return -1-(((0xfc0000 & col) >> 6)|((0xfc00 & col) >> 4)|((0xfc & col) >> 2));
}
Mathieu L Bouchard
committed
void iemgui_all_col2save(t_iemgui *x, int *bflcol)
Mathieu L Bouchard
committed
bflcol[0] = col2save(x->x_bcol);
bflcol[1] = col2save(x->x_fcol);
bflcol[2] = col2save(x->x_lcol);
Mathieu L Bouchard
committed
static int colfromload(int col) {
if(col)
Mathieu L Bouchard
committed
col = -1-col;
return ((col & 0x3f000) << 6)|((col & 0xfc0) << 4)|((col & 0x3f) << 2);
Mathieu L Bouchard
committed
return iemgui_color_hex[iemgui_modulo_color(col)];
}
Mathieu L Bouchard
committed
void iemgui_all_colfromload(t_iemgui *x, int *bflcol)
Mathieu L Bouchard
committed
{
Mathieu L Bouchard
committed
x->x_bcol = colfromload(bflcol[0]);
x->x_fcol = colfromload(bflcol[1]);
x->x_lcol = colfromload(bflcol[2]);
Mathieu L Bouchard
committed
static int iemgui_compatible_col(int i)
Mathieu L Bouchard
committed
return(iemgui_color_hex[(iemgui_modulo_color(i))]);
return((-1-i)&0xffffff);
}
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]);
}
Mathieu L Bouchard
committed
void iemgui_send(t_iemgui *x, t_symbol *s)
Ivica Bukvic
committed
if (s == &s_) s = s_empty; //tb: fix for empty label
Mathieu L Bouchard
committed
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;
Mathieu L Bouchard
committed
x->x_snd_unexpanded = snd;
x->x_snd = snd = canvas_realizedollar(x->x_glist, snd);
iemgui_verify_snd_ne_rcv(x);
Mathieu L Bouchard
committed
iemgui_draw_io(x, oldsndrcvable);
Mathieu L Bouchard
committed
void iemgui_receive(t_iemgui *x, t_symbol *s)
Ivica Bukvic
committed
if (s == &s_) s = s_empty; //tb: fix for empty label
Mathieu L Bouchard
committed
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;
Mathieu L Bouchard
committed
x->x_rcv_unexpanded = rcv;
rcv = canvas_realizedollar(x->x_glist, rcv);
Ivica Bukvic
committed
if(s!=s_empty)
Mathieu L Bouchard
committed
if(rcv!=x->x_rcv)
Mathieu L Bouchard
committed
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);
Ivica Bukvic
committed
else if(s==s_empty && iemgui_has_rcv(x))
Mathieu L Bouchard
committed
pd_unbind((t_pd *)x, x->x_rcv);
x->x_rcv = rcv;
Mathieu L Bouchard
committed
iemgui_verify_snd_ne_rcv(x);
Mathieu L Bouchard
committed
iemgui_draw_io(x, oldsndrcvable);
Mathieu L Bouchard
committed
void iemgui_label(t_iemgui *x, t_symbol *s)
Mathieu L Bouchard
committed
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);
Mathieu L Bouchard
committed
if(glist_isvisible(x->x_glist))
sys_vgui(".x%lx.c itemconfigure %lxLABEL -text {%s} \n",
Mathieu L Bouchard
committed
glist_getcanvas(x->x_glist), x,
s!=s_empty?x->x_lab->s_name:"");
iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_CONFIG);
Mathieu L Bouchard
committed
void iemgui_label_pos(t_iemgui *x, t_symbol *s, int ac, t_atom *av)
Mathieu L Bouchard
committed
x->x_ldx = atom_getintarg(0, ac, av);
x->x_ldy = atom_getintarg(1, ac, av);
Mathieu L Bouchard
committed
if(glist_isvisible(x->x_glist))
{
sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",
Mathieu L Bouchard
committed
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);
Mathieu L Bouchard
committed
void iemgui_label_font(t_iemgui *x, t_symbol *s, int ac, t_atom *av)
Mathieu L Bouchard
committed
int f = atom_getintarg(0, ac, av);
Mathieu L Bouchard
committed
if (f<0 || f>2) f=0;
x->x_font_style = f;
Mathieu L Bouchard
committed
x->x_fontsize = maxi(atom_getintarg(1, ac, av),4);
Mathieu L Bouchard
committed
if(glist_isvisible(x->x_glist))
Mathieu L Bouchard
committed
sys_vgui(".x%lx.c itemconfigure %lxLABEL -font %s\n",
Mathieu L Bouchard
committed
glist_getcanvas(x->x_glist), x, iemgui_font(x),
x->x_fontsize, sys_fontweight);
iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_CONFIG);
}
//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
// 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;
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");
}
t_float width_multiplier;
int label_x1;
int label_y1;
int label_x2;
int label_y2;
int actual_fontsize; //seems tk does its own thing when rendering
int actual_height;
if (x->gl_isgraph && !glist_istoplevel(x))
{
Mathieu L Bouchard
committed
if (x_gui.x_lab!=s_empty)
Mathieu L Bouchard
committed
switch(x_gui.x_font_style)
Mathieu L Bouchard
committed
case 1: width_multiplier = 0.83333; break;
case 2: width_multiplier = 0.735; break;
default: width_multiplier = 1.0; break;
Mathieu L Bouchard
committed
actual_fontsize = x_gui.x_fontsize;
actual_height = actual_fontsize;
Mathieu L Bouchard
committed
if (x_gui.x_font_style == 0 &&
(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;
}
Mathieu L Bouchard
committed
else if (x_gui.x_font_style == 1 && actual_fontsize >= 5 &&
actual_fontsize < 13 && actual_fontsize % 2 == 1)
actual_fontsize += 1;
Mathieu L Bouchard
committed
else if (x_gui.x_font_style == 2 && actual_fontsize >= 5 &&
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,
Mathieu L Bouchard
committed
// label_length, x_gui.x_font_style);
//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);
}
}
}
Mathieu L Bouchard
committed
355
356
357
358
359
360
361
362
363
364
365
366
367
368
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
#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
Mathieu L Bouchard
committed
void iemgui_shouldvis(t_iemgui *x, int mode)
{
gop_redraw = 1;
Mathieu L Bouchard
committed
if(gobj_shouldvis((t_gobj *)x, x->x_glist))
Mathieu L Bouchard
committed
if (!x->x_vis)
{
//fprintf(stderr,"draw new %d\n", mode);
Mathieu L Bouchard
committed
iemgui_draw_new(x);
Mathieu L Bouchard
committed
canvas_fixlinesfor(glist_getcanvas(x->x_glist), (t_text*)x);
x->x_vis = 1;
if (x->x_glist != glist_getcanvas(x->x_glist))
{
/* 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 */
Mathieu L Bouchard
committed
t_canvas *canvas = glist_getcanvas(x->x_glist);
t_gobj *y = (t_gobj *)x->x_glist;
gobj_vis(y, canvas, 0);
gobj_vis(y, canvas, 1);
// reorder it visually
glist_redraw(canvas);
}
}
Mathieu L Bouchard
committed
//fprintf(stderr,"draw move x->x_w=%d\n", x->x_w);
Mathieu L Bouchard
committed
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");
scalehandle_check_and_redraw(x);
Mathieu L Bouchard
committed
canvas_fixlinesfor(glist_getcanvas(x->x_glist), (t_text*)x);
Mathieu L Bouchard
committed
else if (x->x_vis)
{
//fprintf(stderr,"draw erase %d\n", mode);
Mathieu L Bouchard
committed
iemgui_draw_erase(x);
Ivica Bukvic
committed
x->x_vis = 0;
}
gop_redraw = 0;
Mathieu L Bouchard
committed
void iemgui_size(t_iemgui *x)
Mathieu L Bouchard
committed
if(glist_isvisible(x->x_glist))
iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_MOVE);
Mathieu L Bouchard
committed
void iemgui_delta(t_iemgui *x, t_symbol *s, int ac, t_atom *av)
Mathieu L Bouchard
committed
x->x_obj.te_xpix += atom_getintarg(0, ac, av);
x->x_obj.te_ypix += atom_getintarg(1, ac, av);
Mathieu L Bouchard
committed
if(glist_isvisible(x->x_glist))
iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_MOVE);
Mathieu L Bouchard
committed
void iemgui_pos(t_iemgui *x, t_symbol *s, int ac, t_atom *av)
Mathieu L Bouchard
committed
x->x_obj.te_xpix = atom_getintarg(0, ac, av);
x->x_obj.te_ypix = atom_getintarg(1, ac, av);
Mathieu L Bouchard
committed
if(glist_isvisible(x->x_glist))
iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_MOVE);
Mathieu L Bouchard
committed
void iemgui_color(t_iemgui *x, t_symbol *s, int ac, t_atom *av)
Mathieu L Bouchard
committed
x->x_bcol = iemgui_compatible_col(atom_getintarg(0, ac, av));
Mathieu L Bouchard
committed
x->x_fcol = iemgui_compatible_col(atom_getintarg(1, ac, av));
x->x_lcol = iemgui_compatible_col(atom_getintarg(2, ac, av));
Mathieu L Bouchard
committed
x->x_lcol = iemgui_compatible_col(atom_getintarg(1, ac, av));
if(glist_isvisible(x->x_glist))
Mathieu L Bouchard
committed
x->x_draw(x, x->x_glist, IEM_GUI_DRAW_MODE_CONFIG);
iemgui_label_draw_config(x);
}
}
void iemgui_displace(t_gobj *z, t_glist *glist, int dx, int dy)
{
Mathieu L Bouchard
committed
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);
void iemgui_displace_withtag(t_gobj *z, t_glist *glist, int dx, int dy)
{
Mathieu L Bouchard
committed
t_iemgui *x = (t_iemgui *)z;
x->x_obj.te_xpix += dx;
x->x_obj.te_ypix += dy;
Mathieu L Bouchard
committed
//iemgui_draw_move(x);
canvas_fixlinesfor(glist_getcanvas(glist), (t_text *)z);
}
void iemgui_select(t_gobj *z, t_glist *glist, int selected)
{
Mathieu L Bouchard
committed
t_iemgui *x = (t_iemgui *)z;
Mathieu L Bouchard
committed
t_canvas *canvas=glist_getcanvas(glist);
if (selected)
x->x_selected = canvas;
else
x->x_selected = NULL;
Mathieu L Bouchard
committed
char fcol[8]; sprintf(fcol,"#%6.6x", x->x_fcol);
Mathieu L Bouchard
committed
sys_vgui(".x%lx.c itemconfigure {x%lx&&border} -stroke %s\n", canvas, x,
Mathieu L Bouchard
committed
x->x_selected && x->x_glist == canvas ? selection_color : fcol);
Mathieu L Bouchard
committed
x->x_draw((void *)z, glist, IEM_GUI_DRAW_MODE_SELECT);
Mathieu L Bouchard
committed
scalehandle_draw(x);
iemgui_label_draw_select(x);
iemgui_tag_selected(x);
}
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)
{
Mathieu L Bouchard
committed
t_iemgui *x = (t_iemgui *)z;
if (gobj_shouldvis(z, glist))
{
if (vis)
Mathieu L Bouchard
committed
iemgui_draw_new(x);
Mathieu L Bouchard
committed
iemgui_draw_erase(x);
sys_unqueuegui(z);
}
Mathieu L Bouchard
committed
x->x_vis = vis;
Mathieu L Bouchard
committed
void iemgui_save(t_iemgui *x, t_symbol **srl, int *bflcol)
Mathieu L Bouchard
committed
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);
Mathieu L Bouchard
committed
void iemgui_properties(t_iemgui *x, t_symbol **srl)
Mathieu L Bouchard
committed
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]);
int iemgui_dialog(t_iemgui *x, int argc, t_atom *argv)
t_symbol *srl[3];
Mathieu L Bouchard
committed
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;
if(iemgui_has_rcv(x)) oldsndrcvable |= IEM_GUI_OLD_RCV_FLAG;
if(iemgui_has_snd(x)) oldsndrcvable |= IEM_GUI_OLD_SND_FLAG;
Mathieu L Bouchard
committed
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)
Mathieu L Bouchard
committed
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);
Mathieu L Bouchard
committed
x->x_snd = srl[0];
x->x_lab = srl[2];
Mathieu L Bouchard
committed
if(f<0 || f>2) f=0;
Mathieu L Bouchard
committed
x->x_font_style = f;
iemgui_verify_snd_ne_rcv(x);
canvas_dirty(x->x_glist, 1);
return oldsndrcvable;
Mathieu L Bouchard
committed
void iem_inttosymargs(t_iemgui *x, int n)
Mathieu L Bouchard
committed
x->x_loadinit = (n >> 0);
x->x_locked = 0;
x->x_reverse = 0;
Mathieu L Bouchard
committed
int iem_symargstoint(t_iemgui *x)
Mathieu L Bouchard
committed
return ((x->x_loadinit & 1) << 0);
Mathieu L Bouchard
committed
void iem_inttofstyle(t_iemgui *x, int n)
Mathieu L Bouchard
committed
x->x_font_style = (n >> 0);
x->x_selected = NULL;
Mathieu L Bouchard
committed
x->x_finemoved = 0;
x->x_put_in2out = 0;
x->x_change = 0;
}
int iem_fstyletoint(t_iemgui *x)
Mathieu L Bouchard
committed
return ((x->x_font_style << 0) & 63);
//----------------------------------------------------------------
Mathieu L Bouchard
committed
// SCALEHANDLE COMMON CODE (by Mathieu, refactored from existing code)
extern int gfxstub_haveproperties(void *key);
Mathieu L Bouchard
committed
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;}
// 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.
Mathieu L Bouchard
committed
// 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)
Mathieu L Bouchard
committed
void scalehandle_draw_select(t_scalehandle *h, int px, int py) {
char tags[128]; // BNG may need up to 100 chars in 64-bit mode, for example
// casting x as t_object so that it can work both with t_glist (GOP scalehandles)
// and t_iemgui (iemgui scalehandles)
t_object *x = (t_object *)h->h_master;
t_canvas *canvas=glist_getcanvas(h->h_glist);
Mathieu L Bouchard
committed
//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;
//}
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;
Mathieu L Bouchard
committed
scalehandle_draw_erase(h);
Ivica Bukvic
committed
Mathieu L Bouchard
committed
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) {
Ivica Bukvic
committed
sprintf(tags,"x%lx %lxSCALE iemgui selected", (long)x,(long)x);
Mathieu L Bouchard
committed
} else {
Ivica Bukvic
committed
sprintf(tags,"x%lx %lx%s iemgui selected", (long)x,
Mathieu L Bouchard
committed
(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->te_xpix+px-sx, x->te_ypix+py-sy, sx, sy,
Mathieu L Bouchard
committed
h->h_pathname, tags);
scalehandle_bind(h);
h->h_vis = 1;
/* not yet (this is not supported by the current implementation) */
Mathieu L Bouchard
committed
}/* else {
Mathieu L Bouchard
committed
sys_vgui(".x%x.c coords %s %d %d\n", canvas, h->h_pathname,
x->te_xpix+px-sx, x->te_ypix+py-sy);
Mathieu L Bouchard
committed
sys_vgui("raise %s\n", h->h_pathname);
}*/
extern t_class *my_canvas_class;
Mathieu L Bouchard
committed
void scalehandle_draw_select2(t_iemgui *x) {
t_canvas *canvas=glist_getcanvas(x->x_glist);
Mathieu L Bouchard
committed
t_class *c = pd_class((t_pd *)x);
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;
}
Mathieu L Bouchard
committed
scalehandle_draw_select(x->x_handle,sx-1,sy-1);
Mathieu L Bouchard
committed
if (x->x_lab!=s_empty)
Mathieu L Bouchard
committed
scalehandle_draw_select(x->x_lhandle,x->x_ldx,x->x_ldy);
Mathieu L Bouchard
committed
void scalehandle_draw_erase(t_scalehandle *h) {
t_canvas *canvas=glist_getcanvas(h->h_glist);
Mathieu L Bouchard
committed
if (!h->h_vis) return;
sys_vgui("destroy %s\n", h->h_pathname);
Ivica Bukvic
committed
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;
Mathieu L Bouchard
committed
void scalehandle_draw_erase2(t_iemgui *x) {
Mathieu L Bouchard
committed
t_scalehandle *sh = (t_scalehandle *)(x->x_handle);
t_scalehandle *lh = (t_scalehandle *)(x->x_lhandle);
Mathieu L Bouchard
committed
if (sh->h_vis) scalehandle_draw_erase(sh);
if (lh->h_vis) scalehandle_draw_erase(lh);
Mathieu L Bouchard
committed
}
Mathieu L Bouchard
committed
void scalehandle_draw(t_iemgui *x) {
if (x->x_glist == glist_getcanvas(x->x_glist)) {
if(x->x_selected == x->x_glist) scalehandle_draw_select2(x);
else scalehandle_draw_erase2(x);
Mathieu L Bouchard
committed
}
Mathieu L Bouchard
committed
}
Mathieu L Bouchard
committed
t_scalehandle *scalehandle_new(t_class *c, t_gobj *x, t_glist *glist, int scale) {
Mathieu L Bouchard
committed
t_scalehandle *h = (t_scalehandle *)pd_new(c);
char buf[64];
h->h_master = (t_gobj*)x;
Mathieu L Bouchard
committed
h->h_glist = glist;
Mathieu L Bouchard
committed
sprintf(buf, "_h%lx", (t_int)h);
pd_bind((t_pd *)h, h->h_bindsym = gensym(buf));
sprintf(h->h_outlinetag, "h%lx", (t_int)h);
h->h_dragon = 0;
h->h_scale = scale;
//h->h_offset_x = 0; // unused (maybe keep for later)
//h->h_offset_y = 0; // unused (maybe keep for later)
Mathieu L Bouchard
committed
h->h_vis = 0;
Mathieu L Bouchard
committed
sprintf(h->h_pathname, ".x%lx.h%lx", (t_int)h->h_glist, (t_int)h);
Mathieu L Bouchard
committed
return h;
}
void scalehandle_free(t_scalehandle *h) {
pd_unbind((t_pd *)h, h->h_bindsym);
pd_free((t_pd *)h);
Mathieu L Bouchard
committed
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)
{
int new_x = x->x_ldx + h->h_dragx;
int new_y = x->x_ldy + h->h_dragy;
Mathieu L Bouchard
committed
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);
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);
Mathieu L Bouchard
committed
}
}
}
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
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;
}
Ivica Bukvic
committed
// 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
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);
Mathieu L Bouchard
committed
iemgui_io_draw_move(x);
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);
}
}
Mathieu L Bouchard
committed
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;
}
// 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)
{
if(x->x_selected == x->x_glist)
Mathieu L Bouchard
committed
scalehandle_draw_select2(x);
}
Mathieu L Bouchard
committed
//----------------------------------------------------------------
// IEMGUI refactor (by Mathieu)
Mathieu L Bouchard
committed
void iemgui_tag_selected(t_iemgui *x) {
t_canvas *canvas=glist_getcanvas(x->x_glist);
Mathieu L Bouchard
committed
if(x->x_selected)
Mathieu L Bouchard
committed
sys_vgui(".x%lx.c addtag selected withtag x%lx\n", canvas, x);
Mathieu L Bouchard
committed
else
Mathieu L Bouchard
committed
sys_vgui(".x%lx.c dtag x%lx selected\n", canvas, x);
Mathieu L Bouchard
committed
}
Mathieu L Bouchard
committed
void iemgui_label_draw_new(t_iemgui *x) {
t_canvas *canvas=glist_getcanvas(x->x_glist);
Mathieu L Bouchard
committed
int x1=text_xpix(&x->x_obj, x->x_glist);
int y1=text_ypix(&x->x_obj, x->x_glist);
Mathieu L Bouchard
committed
sys_vgui(".x%lx.c create text %d %d -text {%s} -anchor w "
Mathieu L Bouchard
committed
"-font %s -fill #%6.6x -tags {%lxLABEL x%lx text iemgui}\n",
Mathieu L Bouchard
committed
canvas, x1+x->x_ldx, y1+x->x_ldy,
Mathieu L Bouchard
committed
x->x_lab!=s_empty?x->x_lab->s_name:"",
Mathieu L Bouchard
committed
iemgui_font(x), x->x_lcol, x, x);
Mathieu L Bouchard
committed
}
Ivica Bukvic
committed
Mathieu L Bouchard
committed
void iemgui_label_draw_move(t_iemgui *x) {
t_canvas *canvas=glist_getcanvas(x->x_glist);
Mathieu L Bouchard
committed
int x1=text_xpix(&x->x_obj, x->x_glist);
int y1=text_ypix(&x->x_obj, x->x_glist);
Mathieu L Bouchard
committed
sys_vgui(".x%lx.c coords %lxLABEL %d %d\n",
Mathieu L Bouchard
committed
canvas, x, x1+x->x_ldx, y1+x->x_ldy);
Mathieu L Bouchard
committed
}
Ivica Bukvic
committed
Mathieu L Bouchard
committed
void iemgui_label_draw_config(t_iemgui *x) {
t_canvas *canvas=glist_getcanvas(x->x_glist);
if (x->x_selected == canvas && x->x_glist == canvas)
Mathieu L Bouchard
committed
sys_vgui(".x%lx.c itemconfigure %lxLABEL -font %s "
Mathieu L Bouchard
committed
"-fill $pd_colors(selection) -text {%s} \n",
Mathieu L Bouchard
committed
canvas, x, iemgui_font(x),
Mathieu L Bouchard
committed
x->x_lab!=s_empty?x->x_lab->s_name:"");
Mathieu L Bouchard
committed
else
Mathieu L Bouchard
committed
sys_vgui(".x%lx.c itemconfigure %lxLABEL -font %s "
Mathieu L Bouchard
committed
"-fill #%6.6x -text {%s} \n",
Mathieu L Bouchard
committed
canvas, x, iemgui_font(x),
Mathieu L Bouchard
committed
x->x_lcol, x->x_lab!=s_empty?x->x_lab->s_name:"");
if (x->x_selected == canvas && x->x_glist == canvas)
{
t_scalehandle *lh = (t_scalehandle *)(x->x_lhandle);
if (x->x_lab==s_empty)
Mathieu L Bouchard
committed
scalehandle_draw_erase(x->x_lhandle);
else if (lh->h_vis == 0)
Mathieu L Bouchard
committed
scalehandle_draw_select(lh,x->x_ldx,x->x_ldy);
Mathieu L Bouchard
committed
}
Ivica Bukvic
committed
Mathieu L Bouchard
committed
void iemgui_label_draw_select(t_iemgui *x) {
t_canvas *canvas=glist_getcanvas(x->x_glist);
if (x->x_selected == canvas && x->x_glist == canvas)
Mathieu L Bouchard
committed
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);
}
Mathieu L Bouchard
committed
extern t_class *my_numbox_class;
Mathieu L Bouchard
committed
extern t_class *vu_class;
Mathieu L Bouchard
committed
void iemgui_draw_io(t_iemgui *x, int old_sr_flags)
Mathieu L Bouchard
committed
t_canvas *canvas=glist_getcanvas(x->x_glist);
if (x->x_glist != canvas) return; // is gop
Mathieu L Bouchard
committed
t_class *c = pd_class((t_pd *)x);
Mathieu L Bouchard
committed
if (c==my_numbox_class && ((t_my_numbox *)x)->x_hide_frame > 1) return; //sigh
Mathieu L Bouchard
committed
if (!(old_sr_flags&4) && (!glist_isvisible(canvas) || !(canvas == x->x_glist))) {
return;
}
Mathieu L Bouchard
committed
if (c==my_canvas_class) return;
Mathieu L Bouchard
committed
int x1,y1,x2,y2;
c->c_wb->w_getrectfn((t_gobj *)x,canvas,&x1,&y1,&x2,&y2);
Mathieu L Bouchard
committed
int i, n = c==vu_class ? 2 : 1, k=(x2-x1)-IOWIDTH;
Mathieu L Bouchard
committed
int a=old_sr_flags&IEM_GUI_OLD_SND_FLAG;
int b=x->x_snd!=s_empty;
//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);
Mathieu L Bouchard
committed
if(a && !b) for (i=0; i<n; i++)
Mathieu L Bouchard
committed
sys_vgui(".x%lx.c create prect %d %d %d %d "
"-stroke $pd_colors(iemgui_nlet) "
Ivica Bukvic
committed
"-tags {x%lxo%d x%lx outlet %s}\n",
Mathieu L Bouchard
committed
canvas, x1+i*k, y2-1, x1+i*k + IOWIDTH, y2,
Ivica Bukvic
committed
x, i, x, x->x_selected == x->x_glist ? "iemgui selected" : "iemgui");
Mathieu L Bouchard
committed
if(!a && b) for (i=0; i<n; i++)
sys_vgui(".x%lx.c delete x%lxo%d\n", canvas, x, i);
Mathieu L Bouchard
committed
a=old_sr_flags&IEM_GUI_OLD_RCV_FLAG;
b=x->x_rcv!=s_empty;
//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);
Mathieu L Bouchard
committed
if(a && !b) for (i=0; i<n; i++)
Mathieu L Bouchard
committed
sys_vgui(".x%lx.c create prect %d %d %d %d "
"-stroke $pd_colors(iemgui_nlet) "
Ivica Bukvic
committed
"-tags {x%lxi%d x%lx inlet %s}\n",
Mathieu L Bouchard
committed
canvas, x1+i*k, y1, x1+i*k + IOWIDTH, y1+1,
Ivica Bukvic
committed
x, i, x, x->x_selected == x->x_glist ? "iemgui selected" : "iemgui");
Mathieu L Bouchard
committed
if(!a && b) for (i=0; i<n; i++)
sys_vgui(".x%lx.c delete x%lxi%d\n", canvas, x, i);
Mathieu L Bouchard
committed
}
Mathieu L Bouchard
committed
void iemgui_io_draw_move(t_iemgui *x) {
t_canvas *canvas=glist_getcanvas(x->x_glist);
Mathieu L Bouchard
committed
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++)
Mathieu L Bouchard
committed
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);
Mathieu L Bouchard
committed
if(!iemgui_has_rcv(x) && canvas == x->x_glist) for (i=0; i<n; i++)