Commit 8b187ccf authored by Jonathan Wilkes's avatar Jonathan Wilkes
Browse files

Merge branch 'port-drawtext-squashed'

parents 1e02502c 49d94d17
...@@ -748,12 +748,12 @@ static void scalar_displace_withtag(t_gobj *z, t_glist *glist, int dx, int dy) ...@@ -748,12 +748,12 @@ static void scalar_displace_withtag(t_gobj *z, t_glist *glist, int dx, int dy)
t_gobj *y; t_gobj *y;
t_canvas *templatecanvas = template_findcanvas(template); t_canvas *templatecanvas = template_findcanvas(template);
for (y = templatecanvas->gl_list; y; y = y->g_next) for (y = templatecanvas->gl_list; y; y = y->g_next)
{ {
t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd); t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd);
if (!wb) continue; if (!wb) continue;
(*wb->w_parentdisplacefn)(y, glist, x->sc_vec, template, (*wb->w_parentdisplacefn)(y, glist, x->sc_vec, template,
basex, basey, dx, dy); basex, basey, dx, dy);
} }
} }
*/ */
......
...@@ -4269,12 +4269,9 @@ static void draw_vis(t_gobj *z, t_glist *glist, t_glist *parentglist, ...@@ -4269,12 +4269,9 @@ static void draw_vis(t_gobj *z, t_glist *glist, t_glist *parentglist,
} }
} }
//static int draw_motion_field;
static t_float draw_motion_xcumulative; static t_float draw_motion_xcumulative;
//static t_float draw_motion_xbase;
static t_float draw_motion_xper; static t_float draw_motion_xper;
static t_float draw_motion_ycumulative; static t_float draw_motion_ycumulative;
//static t_float draw_motion_ybase;
static t_float draw_motion_yper; static t_float draw_motion_yper;
static t_glist *draw_motion_glist; static t_glist *draw_motion_glist;
static t_scalar *draw_motion_scalar; static t_scalar *draw_motion_scalar;
...@@ -7014,531 +7011,49 @@ static void drawarray_setup(void) ...@@ -7014,531 +7011,49 @@ static void drawarray_setup(void)
class_setparentwidget(drawarray_class, &drawarray_widgetbehavior); class_setparentwidget(drawarray_class, &drawarray_widgetbehavior);
} }
/* ---------------- drawnumber: draw a number (or symbol) ---------------- */ /* ---------------- drawnumber, drawsymbol, drawtext ------------ */
/* t_class *drawsymbol_class;
drawnumbers draw numeric fields at controllable locations, with
controllable color and label. invocation:
(drawnumber|drawsymbol) [-v <visible>] variable x y color label
*/
t_class *drawnumber_class;
#define DRAW_SYMBOL 1
typedef struct _drawnumber typedef struct _drawsymbol
{ {
t_object x_obj; t_object x_obj;
t_fielddesc x_value; t_symbol *x_fieldname;
t_fielddesc x_xloc; t_fielddesc x_xloc;
t_fielddesc x_yloc; t_fielddesc x_yloc;
t_fielddesc x_color; t_fielddesc x_color;
t_fielddesc x_vis; t_fielddesc x_vis;
t_fielddesc x_fontsize; t_fielddesc x_fontsize;
t_symbol *x_label; t_symbol *x_label;
int x_flags;
t_canvas *x_canvas; t_canvas *x_canvas;
} t_drawnumber; int x_wanttype;
int x_typerror;
} t_drawsymbol;
static void *drawnumber_new(t_symbol *classsym, t_int argc, t_atom *argv) static void *drawsymbol_new(t_symbol *classsym, t_int argc, t_atom *argv)
{ {
if (legacy_draw_in_group(canvas_getcurrent())) if (legacy_draw_in_group(canvas_getcurrent()))
return 0; return 0;
t_drawnumber *x = (t_drawnumber *)pd_new(drawnumber_class); t_drawsymbol *x = (t_drawsymbol *)pd_new(drawsymbol_class);
char *classname = classsym->s_name;
int flags = 0;
int got_font_size = 0;
if (classname[4] == 's')
flags |= DRAW_SYMBOL;
x->x_flags = flags;
fielddesc_setfloat_const(&x->x_vis, 1);
x->x_canvas = canvas_getcurrent();
while (1)
{
t_symbol *firstarg = atom_getsymbolarg(0, argc, argv);
if (!strcmp(firstarg->s_name, "-v") && argc > 1)
{
fielddesc_setfloatarg(&x->x_vis, 1, argv+1);
argc -= 2; argv += 2;
}
else break;
}
if (flags & DRAW_SYMBOL)
{
if (argc) fielddesc_setsymbolarg(&x->x_value, argc--, argv++);
else fielddesc_setsymbol_const(&x->x_value, &s_);
}
else
{
if (argc) fielddesc_setfloatarg(&x->x_value, argc--, argv++);
else fielddesc_setfloat_const(&x->x_value, 0);
}
if (argc) fielddesc_setfloatarg(&x->x_xloc, argc--, argv++);
else fielddesc_setfloat_const(&x->x_xloc, 0);
if (argc) fielddesc_setfloatarg(&x->x_yloc, argc--, argv++);
else fielddesc_setfloat_const(&x->x_yloc, 0);
if (argc) fielddesc_setfloatarg(&x->x_color, argc--, argv++);
else fielddesc_setfloat_const(&x->x_color, 1);
if (argc == 2)
{
fielddesc_setfloatarg(&x->x_fontsize, argc--, argv++);
got_font_size = 1;
}
if (argc)
{
if (argv->a_type == A_SYMBOL || got_font_size)
{
x->x_label = atom_getsymbolarg(0, argc, argv);
if (!got_font_size)
fielddesc_setfloatarg(&x->x_fontsize, 0, NULL);
}
else if (argv->a_type == A_FLOAT)
{
fielddesc_setfloatarg(&x->x_fontsize, argc, argv);
x->x_label = &s_;
}
} else {
fielddesc_setfloatarg(&x->x_fontsize, 0, NULL);
x->x_label = &s_;
}
return (x);
}
void drawnumber_float(t_drawnumber *x, t_floatarg f)
{
int viswas;
if (x->x_vis.fd_type != A_FLOAT || x->x_vis.fd_var)
{
pd_error(x, "global vis/invis for a template with variable visibility");
return;
}
viswas = (x->x_vis.fd_un.fd_float != 0);
if ((f != 0 && viswas) || (f == 0 && !viswas))
return;
canvas_redrawallfortemplatecanvas(x->x_canvas, 2);
fielddesc_setfloat_const(&x->x_vis, (f != 0));
canvas_redrawallfortemplatecanvas(x->x_canvas, 1);
}
/* -------------------- widget behavior for drawnumber ------------ */
/*#define DRAWNUMBER_BUFSIZE 80
static void drawnumber_sprintf(t_drawnumber *x, char *buf, t_atom *ap)
{
int nchars;
strncpy(buf, x->x_label->s_name, DRAWNUMBER_BUFSIZE);
buf[DRAWNUMBER_BUFSIZE - 1] = 0;
nchars = strlen(buf);
atom_string(ap, buf + nchars, DRAWNUMBER_BUFSIZE - nchars);
}*/
static int drawnumber_gettype(t_drawnumber *x, t_word *data,
t_template *template, int *onsetp)
{
int type;
t_symbol *arraytype;
if (template_find_field(template, /*x->x_fieldname*/ x->x_value.fd_un.fd_varsym, onsetp, &type,
&arraytype) && type != DT_ARRAY)
return (type);
else return (-1);
}
#define DRAWNUMBER_BUFSIZE 1024
static void drawnumber_getbuf(t_drawnumber *x, t_word *data,
t_template *template, char *buf)
{
int nchars, onset, type = drawnumber_gettype(x, data, template, &onset);
if (type < 0)
buf[0] = 0;
else
{
strncpy(buf, x->x_label->s_name, DRAWNUMBER_BUFSIZE);
buf[DRAWNUMBER_BUFSIZE - 1] = 0;
nchars = strlen(buf);
if (type == DT_TEXT)
{
char *buf2;
int size2, ncopy;
binbuf_gettext(((t_word *)((char *)data + onset))->w_binbuf,
&buf2, &size2);
ncopy = (size2 > DRAWNUMBER_BUFSIZE-1-nchars ?
DRAWNUMBER_BUFSIZE-1-nchars: size2);
memcpy(buf+nchars, buf2, ncopy);
buf[nchars+ncopy] = 0;
if (nchars+ncopy == DRAWNUMBER_BUFSIZE-1)
strcpy(buf+(DRAWNUMBER_BUFSIZE-4), "...");
t_freebytes(buf2, size2);
}
else
{
t_atom at;
if (type == DT_FLOAT)
SETFLOAT(&at, ((t_word *)((char *)data + onset))->w_float);
else SETSYMBOL(&at, ((t_word *)((char *)data + onset))->w_symbol);
atom_string(&at, buf + nchars, DRAWNUMBER_BUFSIZE - nchars);
}
}
}
static void drawnumber_getrect(t_gobj *z, t_glist *glist,
t_word *data, t_template *template, t_float basex, t_float basey,
int *xp1, int *yp1, int *xp2, int *yp2)
{
t_drawnumber *x = (t_drawnumber *)z;
t_atom at;
int xloc, yloc, font, fontwidth, fontheight;
char buf[DRAWNUMBER_BUFSIZE];
if (!fielddesc_getfloat(&x->x_vis, template, data, 0))
{
*xp1 = *yp1 = 0x7fffffff;
*xp2 = *yp2 = -0x7fffffff;
return;
}
/* hack to keep the font scaling with the gop */
t_float xscale = glist_xtopixels(glist, 1) - glist_xtopixels(glist, 0);
t_float yscale = glist_ytopixels(glist, 1) - glist_ytopixels(glist, 0);
xloc = glist_xtopixels(glist,
basex + fielddesc_getcoord(&x->x_xloc, template, data, 0));
yloc = glist_ytopixels(glist,
basey + fielddesc_getcoord(&x->x_yloc, template, data, 0));
font = fielddesc_getfloat(&x->x_fontsize, template, data, 0);
if (!font) font = glist_getfont(glist);
fontwidth = sys_fontwidth(font);
fontheight = sys_fontheight(font);
if (x->x_flags & DRAW_SYMBOL)
SETSYMBOL(&at, fielddesc_getsymbol(&x->x_value, template, data, 0));
else SETFLOAT(&at, fielddesc_getfloat(&x->x_value, template, data, 0));
//drawnumber_sprintf(x, buf, &at);
drawnumber_getbuf(x, data, template, buf);
*xp1 = xloc;
*yp1 = yloc;
// Ico 20140830: another regression from the 20140731 where getrect is not accurate
// this, in addition to the vis call fix makes things work right again
// namely, this fixes the getrect inconsistency, while the one in the vis
// function fixes sizing problems
*xp2 = xloc + (fontwidth * strlen(buf) * xscale);
*yp2 = yloc + (fontheight * yscale);
//*xp2 = xloc + (fontwidth * strlen(buf));
//*yp2 = yloc + (fontheight);
}
static void drawnumber_displace(t_gobj *z, t_glist *glist,
t_word *data, t_template *template, t_float basex, t_float basey,
int dx, int dy)
{
/* refuse */
}
static void drawnumber_select(t_gobj *z, t_glist *glist,
t_word *data, t_template *template, t_float basex, t_float basey,
int state)
{
//fprintf(stderr,"drawnumber_select %d", state);
/* fill in later */
}
static void drawnumber_activate(t_gobj *z, t_glist *glist,
t_word *data, t_template *template, t_float basex, t_float basey,
int state)
{
//post("drawnumber_activate %d", state);
}
static void drawnumber_vis(t_gobj *z, t_glist *glist, t_glist *parentglist,
t_scalar *sc, t_word *data, t_template *template,
t_float basex, t_float basey, t_array *parentarray, int vis)
{
//fprintf(stderr,"drawnumber_vis %d\n", vis);
t_drawnumber *x = (t_drawnumber *)z;
/*// get the universal tag for all nested objects
t_canvas *tag = x->x_canvas;
while (tag->gl_owner)
{
tag = tag->gl_owner;
}*/
/* see comment in plot_vis() */
//if (vis && !fielddesc_getfloat(&x->x_vis, template, data, 0))
// return;
if (vis)
{
t_atom at;
int in_array = (sc->sc_vec == data) ? 0 : 1;
// Ico: why are we using scale here? For group transforms? I thought
// that drawsymbol was not eligible for group transforms since it is
// a legacy object? keepin xscale and yscale 1.0 makes things look good
// again on the disis_wiimote-help.pd patch
t_float xscale = 1.0;
t_float yscale = 1.0;
/*t_float xscale = glist_xtopixels(glist, 1) - glist_xtopixels(glist, 0);
t_float yscale = glist_ytopixels(glist, 1) - glist_ytopixels(glist, 0);
if (xscale != 0) xscale = 1.0 / xscale;
if (yscale != 0) yscale = 1.0 / yscale;*/
int fontsize = fielddesc_getfloat(&x->x_fontsize, template, data, 0);
if (!fontsize) fontsize = glist_getfont(glist);
/*int xloc = glist_xtopixels(glist,
basex + fielddesc_getcoord(&x->x_xloc, template, data, 0));
int yloc = glist_ytopixels(glist,
basey + fielddesc_getcoord(&x->x_yloc, template, data, 0));*/
int xloc = fielddesc_getcoord(&x->x_xloc, template, data, 0);
int yloc = fielddesc_getcoord(&x->x_yloc, template, data, 0);
char colorstring[20], buf[DRAWNUMBER_BUFSIZE];
numbertocolor(fielddesc_getfloat(&x->x_color, template, data, 1),
colorstring);
if (x->x_flags & DRAW_SYMBOL)
SETSYMBOL(&at, fielddesc_getsymbol(&x->x_value, template, data, 0));
else SETFLOAT(&at, fielddesc_getfloat(&x->x_value, template, data, 0));
drawnumber_getbuf(x, data, template, buf);
//drawnumber_sprintf(x, buf, &at);
char parent_tagbuf[MAXPDSTRING];
sprintf(parent_tagbuf, "dgroup%lx.%lx",
(in_array ? (long unsigned int)parentglist :
(long unsigned int)x->x_canvas),
(long unsigned int)data);
char tagbuf[MAXPDSTRING];
sprintf(tagbuf, "drawnumber%lx.%lx", (long unsigned int)x, (long unsigned int)data);
gui_vmess("gui_drawnumber_vis", "xssiiffsissii",
glist_getcanvas(glist),
parent_tagbuf,
tagbuf,
xloc,
yloc, // Wrong-- we need to take font height into account
xscale,
yscale,
sys_font,
fontsize,
colorstring,
buf,
vis,
(int)fielddesc_getfloat(&x->x_vis, template, data, 0));
}
else
{
char tagbuf[MAXPDSTRING];
sprintf(tagbuf, "drawnumber%lx.%lx", (long unsigned int)x, (long unsigned int)data);
gui_vmess("gui_draw_erase_item", "xs", glist_getcanvas(glist),
tagbuf);
}
}
static t_float drawnumber_motion_ycumulative;
static t_glist *drawnumber_motion_glist;
static t_scalar *drawnumber_motion_scalar;
static t_array *drawnumber_motion_array;
static t_word *drawnumber_motion_wp;
static t_template *drawnumber_motion_template;
static t_gpointer drawnumber_motion_gpointer;
static int drawnumber_motion_symbol;
static int drawnumber_motion_firstkey;
/* LATER protect against the template changing or the scalar disappearing
probably by attaching a gpointer here ... */
static void drawnumber_motion(void *z, t_floatarg dx, t_floatarg dy)
{
t_drawnumber *x = (t_drawnumber *)z;
t_fielddesc *f = &x->x_value;
t_atom at;
if (!gpointer_check(&drawnumber_motion_gpointer, 0))
{
post("drawnumber_motion: scalar disappeared");
return;
}
if (drawnumber_motion_symbol)
{
post("drawnumber_motion: symbol");
return;
}
drawnumber_motion_ycumulative -= dy;
template_setfloat(drawnumber_motion_template,
f->fd_un.fd_varsym,
drawnumber_motion_wp,
drawnumber_motion_ycumulative,
1);
if (drawnumber_motion_scalar)
template_notifyforscalar(drawnumber_motion_template,
drawnumber_motion_glist, drawnumber_motion_scalar,
gensym("change"), 1, &at);
if (drawnumber_motion_scalar)
scalar_redraw(drawnumber_motion_scalar, drawnumber_motion_glist);
if (drawnumber_motion_array)
array_redraw(drawnumber_motion_array, drawnumber_motion_glist);
}
static void drawnumber_key(void *z, t_floatarg fkey) /* cache our expected field type for when we vis. Otherwise
{ the user can display any field with any creator to cause
t_drawnumber *x = (t_drawnumber *)z; subtle widgetbehavior errors down the line. */
t_fielddesc *f = &x->x_value; if (classsym == gensym("drawnumber")) x->x_wanttype = DT_FLOAT;
int key = fkey; else if (classsym == gensym("drawsymbol")) x->x_wanttype = DT_SYMBOL;
char sbuf[MAXPDSTRING]; else if (classsym == gensym("drawtext")) x->x_wanttype = DT_TEXT;
t_atom at;
if (!gpointer_check(&drawnumber_motion_gpointer, 0))
{
post("drawnumber_motion: scalar disappeared");
return;
}
if (key == 0)
return;
if (drawnumber_motion_symbol)
{
/* key entry for a symbol field */
if (drawnumber_motion_firstkey)
sbuf[0] = 0;
else strncpy(sbuf, template_getsymbol(drawnumber_motion_template,
f->fd_un.fd_varsym, drawnumber_motion_wp, 1)->s_name,
MAXPDSTRING);
sbuf[MAXPDSTRING-1] = 0;
if (key == '\b')
{
if (*sbuf)
sbuf[strlen(sbuf)-1] = 0;
}
else
{
sbuf[strlen(sbuf)+1] = 0;
sbuf[strlen(sbuf)] = key;
}
}
else else
{ {
/* key entry for a numeric field. This is just a stopgap. */ pd_error(x, "drawnumber: unknown type");
float newf; return (0);
if (drawnumber_motion_firstkey)
sbuf[0] = 0;
else sprintf(sbuf, "%g", template_getfloat(drawnumber_motion_template,
f->fd_un.fd_varsym, drawnumber_motion_wp, 1));
drawnumber_motion_firstkey = (key == '\n');
if (key == '\b')
{
if (*sbuf)
sbuf[strlen(sbuf)-1] = 0;
}
else
{
sbuf[strlen(sbuf)+1] = 0;
sbuf[strlen(sbuf)] = key;
}
if (sscanf(sbuf, "%g", &newf) < 1)
newf = 0;
template_setfloat(drawnumber_motion_template,
f->fd_un.fd_varsym, drawnumber_motion_wp, newf, 1);
if (drawnumber_motion_scalar)
template_notifyforscalar(drawnumber_motion_template,
drawnumber_motion_glist, drawnumber_motion_scalar,
gensym("change"), 1, &at);
if (drawnumber_motion_scalar)
scalar_redraw(drawnumber_motion_scalar, drawnumber_motion_glist);
if (drawnumber_motion_array)
array_redraw(drawnumber_motion_array, drawnumber_motion_glist);
}
}
static int drawnumber_click(t_gobj *z, t_glist *glist,
t_word *data, t_template *template, t_scalar *sc, t_array *ap,
t_float basex, t_float basey,
int xpix, int ypix, int shift, int alt, int dbl, int doit)
{
t_drawnumber *x = (t_drawnumber *)z;
int x1, y1, x2, y2;
drawnumber_getrect(z, glist,
data, template, basex, basey,
&x1, &y1, &x2, &y2);
if (xpix >= x1 && xpix <= x2 && ypix >= y1 && ypix <= y2
&& x->x_value.fd_var &&
fielddesc_getfloat(&x->x_vis, template, data, 0))
{
if (doit)
{
drawnumber_motion_glist = glist;
drawnumber_motion_wp = data;
drawnumber_motion_template = template;
drawnumber_motion_scalar = sc;
drawnumber_motion_array = ap;
drawnumber_motion_firstkey = 1;
drawnumber_motion_ycumulative =
fielddesc_getfloat(&x->x_value, template, data, 0);
drawnumber_motion_symbol = ((x->x_flags & DRAW_SYMBOL) != 0);
if (drawnumber_motion_scalar)
gpointer_setglist(&drawnumber_motion_gpointer,
drawnumber_motion_glist, &drawnumber_motion_scalar->sc_gobj);
else gpointer_setarray(&drawnumber_motion_gpointer,
drawnumber_motion_array, drawnumber_motion_wp);
glist_grab(glist, z, drawnumber_motion, drawnumber_key,
xpix, ypix);
}
return (1);
} }
else return (0);
}
t_parentwidgetbehavior drawnumber_widgetbehavior =
{
drawnumber_getrect,
drawnumber_displace,
drawnumber_select,
drawnumber_activate,
drawnumber_vis,
drawnumber_click,
};
static void drawnumber_free(t_drawnumber *x)
{
}
static void drawnumber_setup(void)
{
drawnumber_class = class_new(gensym("drawnumber"),
(t_newmethod)drawnumber_new, (t_method)drawnumber_free,
sizeof(t_drawnumber), 0, A_GIMME, 0);
class_setdrawcommand(drawnumber_class);
class_addfloat(drawnumber_class, drawnumber_float);
class_setparentwidget(drawnumber_class, &drawnumber_widgetbehavior);
}
/* ---------------------- drawsymbol -------------------------------- */
t_class *drawsymbol_class;
typedef struct _drawsymbol
{
t_object x_obj;
t_fielddesc x_value;
t_fielddesc x_xloc;
t_fielddesc x_yloc;
t_fielddesc x_color;
t_fielddesc x_vis;
t_fielddesc x_fontsize;
t_symbol *x_label;
int x_flags;
t_canvas *x_canvas;
} t_drawsymbol;
static void *drawsymbol_new(t_symbol *classsym, t_int argc, t_atom *argv) fielddesc_setfloat_const(&x->x_vis, 1);
{ x->x_canvas = canvas_getcurrent();
if (legacy_draw_in_group(canvas_getcurrent()))
return 0;
t_drawsymbol *x = (t_drawsymbol *)pd_new(drawsymbol_class);
char *classname = classsym->s_name;
int flags = 0;
int got_font_size = 0; int got_font_size = 0;
if (classname[4] == 's')
flags |= DRAW_SYMBOL;
x->x_flags = flags;
fielddesc_setfloat_const(&x->x_vis, 1);
x->x_canvas = canvas_getcurrent();
while (1) while (1)
{ {
t_symbol *firstarg = atom_getsymbolarg(0, argc, argv); t_symbol *firstarg = atom_getsymbolarg(0, argc, argv);
...@@ -7549,16 +7064,18 @@ static void *drawsymbol_new(t_symbol *classsym, t_int argc, t_atom *argv) ...@@ -7549,16 +7064,18 @@ static void *drawsymbol_new(t_symbol *classsym, t_int argc, t_atom *argv)
} }
else break; else break;
} }
if (flags & DRAW_SYMBOL)
{ /* if the first arg exists, typecheck it. While it's allowed to have
if (argc) fielddesc_setsymbolarg(&x->x_value, argc--, argv++); no args at all we want to error out if we get the wrong type. */
else fielddesc_setsymbol_const(&x->x_value, &s_); if (argc && argv->a_type != A_SYMBOL)
}
else
{ {
if (argc) fielddesc_setfloatarg(&x->x_value, argc--, argv++); error("%s: first argument (field name) must be a symbol",
else fielddesc_setfloat_const(&x->x_value, 0); classsym->s_name);
return (0);
} }
x->x_fieldname = atom_getsymbolarg(0, argc, argv);
if (argc) argc--, argv++;
if (argc) fielddesc_setfloatarg(&x->x_xloc, argc--, argv++); if (argc) fielddesc_setfloatarg(&x->x_xloc, argc--, argv++);
else fielddesc_setfloat_const(&x->x_xloc, 0); else fielddesc_setfloat_const(&x->x_xloc, 0);
if (argc) fielddesc_setfloatarg(&x->x_yloc, argc--, argv++); if (argc) fielddesc_setfloatarg(&x->x_yloc, argc--, argv++);
...@@ -7589,6 +7106,13 @@ static void *drawsymbol_new(t_symbol *classsym, t_int argc, t_atom *argv) ...@@ -7589,6 +7106,13 @@ static void *drawsymbol_new(t_symbol *classsym, t_int argc, t_atom *argv)
x->x_label = &s_; x->x_label = &s_;
} }
/* We don't yet know whether our field exists. Since this code