Commit 7c6a934a authored by Ivica Bukvic's avatar Ivica Bukvic
Browse files

*patch to add [group] data structure and supporting fixes (work in progress...

*patch to add [group] data structure and supporting fixes (work in progress with lingering bug of being unable to display data structure arrays properly, see tiger.pd demo patch in data structures)
parent 3748ebe1
......@@ -939,6 +939,8 @@ int glist_getfont(t_glist *x)
return (x->gl_font);
}
extern void canvas_group_free(t_pd *x);
void canvas_free(t_canvas *x)
{
//fprintf(stderr,"canvas_free %lx\n", x);
......@@ -970,6 +972,8 @@ void canvas_free(t_canvas *x)
gfxstub_deleteforkey(x); /* probably unnecessary */
if (!x->gl_owner)
canvas_takeofflist(x);
if (x->gl_svg) /* for groups, free the data */
canvas_group_free(x->gl_svg);
}
/* ----------------- lines ---------- */
......@@ -1092,11 +1096,26 @@ static void canvas_pop(t_canvas *x, t_floatarg fvis)
//fprintf(stderr,"loading = 0 .x%lx owner=.x%lx\n", x, x->gl_owner);
}
extern void *svg_new(t_pd *x, t_symbol *s, int argc, t_atom *argv);
extern t_pd *svg_header(t_pd *x);
static void group_svginit(t_glist *gl)
{
gl->gl_svg = (t_pd *)(svg_new((t_pd *)gl, gensym("group"), 0, 0));
t_pd *proxy = svg_header(gl->gl_svg);
inlet_new(&gl->gl_obj, proxy, 0, 0);
}
void canvas_objfor(t_glist *gl, t_text *x, int argc, t_atom *argv);
void canvas_restore(t_canvas *x, t_symbol *s, int argc, t_atom *argv)
{
t_pd *z;
/* for [group] we add an inlet to the svg attr proxy */
if (argc > 2 && argv[2].a_w.w_symbol == gensym("group"))
{
group_svginit(x);
}
if (argc > 3)
{
t_atom *ap=argv+3;
......@@ -1310,6 +1329,12 @@ static void *subcanvas_new(t_symbol *s)
return (x);
}
static void *group_new(t_symbol *s)
{
t_canvas *x = subcanvas_new(s);
group_svginit(x);
return (x);
}
static void canvas_click(t_canvas *x,
t_floatarg xpos, t_floatarg ypos,
t_floatarg shift, t_floatarg ctrl, t_floatarg alt)
......@@ -1671,9 +1696,11 @@ void canvas_redrawallfortemplate(t_template *template, int action)
/* find the template defined by a canvas, and redraw all elements
for that */
extern t_canvas *canvas_templatecanvas_forgroup(t_canvas *x);
void canvas_redrawallfortemplatecanvas(t_canvas *x, int action)
{
//fprintf(stderr,"canvas_redrawallfortemplatecanvas\n");
fprintf(stderr,"canvas_redrawallfortemplatecanvas\n");
t_gobj *g;
t_template *tmpl;
t_symbol *s1 = gensym("struct");
......@@ -2291,6 +2318,7 @@ void g_canvas_setup(void)
/* ----- subcanvases, which you get by typing "pd" in a box ---- */
class_addcreator((t_newmethod)subcanvas_new, gensym("pd"), A_DEFSYMBOL, 0);
class_addcreator((t_newmethod)subcanvas_new, gensym("page"), A_DEFSYMBOL, 0);
class_addcreator((t_newmethod)group_new, gensym("group"), A_DEFSYM, 0);
class_addmethod(canvas_class, (t_method)canvas_click,
gensym("click"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
......@@ -2305,6 +2333,11 @@ void g_canvas_setup(void)
class_addcreator((t_newmethod)table_new, gensym("table"),
A_DEFSYM, A_DEFFLOAT, 0);
/*--------------------------- svg groups ---------------------- */
class_addcreator((t_newmethod)group_new, gensym("group"),
A_DEFSYM, A_DEFFLOAT, 0);
/*---------------------------- declare ------------------- */
declare_class = class_new(gensym("declare"), (t_newmethod)declare_new,
(t_method)declare_free, sizeof(t_declare), CLASS_NOINLET, A_GIMME, 0);
......
......@@ -225,6 +225,7 @@ struct _glist
int move_offset_x;
int move_offset_y;
int move_vis;
t_pd *gl_svg;
};
#define gl_gobj gl_obj.te_g
......@@ -367,7 +368,8 @@ typedef void (*t_parentactivatefn)(t_gobj *x, struct _glist *glist,
t_word *data, t_template *tmpl, t_float basex, t_float basey,
int state);
/* making visible or invisible */
typedef void (*t_parentvisfn)(t_gobj *x, struct _glist *glist, t_scalar *sc,
typedef void (*t_parentvisfn)(t_gobj *x, struct _glist *glist,
struct _glist *parentglist, t_scalar *sc,
t_word *data, t_template *tmpl, t_float basex, t_float basey,
int flag);
/* field a mouse click */
......
......@@ -38,6 +38,30 @@ int gop_redraw = 0;
void canvas_drawredrect(t_canvas *x, int doit);
static int canvas_isgroup(t_canvas *x)
{
/* t_binbuf *b = x->gl_obj.te_binbuf;
if (!b)
{
bug("canvas_isgroup");
return 0;
}
t_atom *argv = binbuf_getvec(x->gl_obj.te_binbuf);
if (argv[0].a_type == A_SYMBOL &&
argv[0].a_w.w_symbol == gensym("group"))
return 1;
else
return 0;
*/
if (x->gl_svg)
return 1;
else
return 0;
}
extern t_template *canvas_findtemplate(t_canvas *c);
extern t_canvas *canvas_templatecanvas_forgroup(t_canvas *c);
void glist_add(t_glist *x, t_gobj *y)
{
//fprintf(stderr,"glist_add %lx %d\n", (t_int)x, (x->gl_editor ? 1 : 0));
......@@ -74,6 +98,14 @@ void glist_add(t_glist *x, t_gobj *y)
t_template *tmpl = template_findbydrawcommand(y);
canvas_redrawallfortemplate(tmpl, 0);
}
if (pd_class(&y->g_pd) == canvas_class &&
canvas_isgroup((t_canvas *)y))
{
t_canvas *templatecanvas =
canvas_templatecanvas_forgroup((t_canvas *)y);
t_template *tmpl = canvas_findtemplate(templatecanvas);
canvas_redrawallfortemplate(tmpl, 0);
}
}
/* this is to protect against a hairy problem in which deleting
......@@ -422,8 +454,7 @@ void canvas_resortinlets(t_canvas *x)
for (ninlets = 0, y = x->gl_list; y; y = y->g_next)
if (pd_class(&y->g_pd) == vinlet_class) ninlets++;
if (ninlets < 2) return;
if (ninlets < 2 && !(canvas_isgroup(x))) return;
vec = (t_gobj **)getbytes(ninlets * sizeof(*vec));
for (y = x->gl_list, vp = vec; y; y = y->g_next)
......
......@@ -273,6 +273,38 @@ static void scalar_mouseover(t_scalar *x, t_floatarg state)
x, gensym("enter"), 1, at);
}
static void scalar_getgrouprect(t_glist *owner, t_glist *groupcanvas,
t_word *data, t_template *template, int basex, int basey,
int *x1, int *x2, int *y1, int *y2)
{
t_gobj *y;
for (y = groupcanvas->gl_list; y; y = y->g_next)
{
if (pd_class(&y->g_pd) == canvas_class &&
((t_canvas *)y)->gl_svg)
{
/* todo: accumulate basex and basey for correct offset */
scalar_getgrouprect(owner, (t_glist *)y, data, template,
basex, basey, x1, x2, y1, y2);
}
else
{
t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd);
int nx1, ny1, nx2, ny2;
if (!wb) continue;
(*wb->w_parentgetrectfn)(y, owner,
data, template, basex, basey,
&nx1, &ny1, &nx2, &ny2);
if (nx1 < *x1) *x1 = nx1;
if (ny1 < *y1) *y1 = ny1;
if (nx2 > *x2) *x2 = nx2;
if (ny2 > *y2) *y2 = ny2;
//fprintf(stderr,"====scalar_getrect x1 %d y1 %d x2 %d y2 %d\n",
// x1, y1, x2, y2);
}
}
}
static void scalar_getrect(t_gobj *z, t_glist *owner,
int *xp1, int *yp1, int *xp2, int *yp2)
{
......@@ -288,7 +320,7 @@ static void scalar_getrect(t_gobj *z, t_glist *owner,
// EXPERIMENTAL: we assume that entire canvas is within
// the rectangle--this is for arrays
// with "jump on click" enabled TODO: test for other regressions
// (there shouuld not be any
// (there should not be any
// provided the global variable array_joc is properly maintained)
if (glist_istoplevel(owner) && array_joc)
{
......@@ -318,22 +350,9 @@ static void scalar_getrect(t_gobj *z, t_glist *owner,
}
x1 = y1 = 0x7fffffff;
x2 = y2 = -0x7fffffff;
for (y = templatecanvas->gl_list; y; y = y->g_next)
{
t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd);
int nx1, ny1, nx2, ny2;
if (!wb) continue;
(*wb->w_parentgetrectfn)(y, owner,
x->sc_vec, template, basex, basey,
&nx1, &ny1, &nx2, &ny2);
if (nx1 < x1) x1 = nx1;
if (ny1 < y1) y1 = ny1;
if (nx2 > x2) x2 = nx2;
if (ny2 > y2) y2 = ny2;
//fprintf(stderr,"====scalar_getrect x1 %d y1 %d x2 %d y2 %d\n",
// x1, y1, x2, y2);
}
if (x2 < x1 || y2 < y1)
scalar_getgrouprect(owner, templatecanvas, x->sc_vec, template,
basex, basey, &x1, &x2, &y1, &y2);
if (x2 < x1 || y2 < y1)
x1 = y1 = x2 = y2 = 0;
}
}
......@@ -639,6 +658,36 @@ static void scalar_delete(t_gobj *z, t_glist *glist)
/* nothing to do */
}
extern void svg_grouptogui(t_glist *g, t_template *template, t_word *data);
static void scalar_groupvis(t_scalar *x, t_glist *owner, t_template *template,
t_glist *gl, t_glist *parent, int vis)
{
t_gobj *y;
if (vis)
{
sys_vgui(".x%lx.c create group -tags {.dgroup%lx.%lx} "
"-parent {.dgroup%lx.%lx}\\\n",
glist_getcanvas(owner), gl, x->sc_vec,
parent, x->sc_vec);
svg_grouptogui(gl, template, x->sc_vec);
sys_gui("\n");
}
for (y = gl->gl_list; y; y = y->g_next)
{
if (pd_class(&y->g_pd) == canvas_class &&
((t_glist *)y)->gl_svg)
{
scalar_groupvis(x, owner, template, (t_glist *)y, gl, vis);
}
t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd);
if (!wb) continue;
(*wb->w_parentvisfn)(y, owner, gl, x, x->sc_vec, template,
0, 0, vis);
}
}
/* At present, scalars have a three-level hierarchy in tkpath,
with two levels accessible by the user from within Pd:
scalar - tkpath group with matrix derived from x/y fields,
......@@ -647,14 +696,19 @@ static void scalar_delete(t_gobj *z, t_glist *glist)
| [draw group] below can ignore basexy and gop junk
| when computing the transform matrix.
v
dgroup - user-facing group which is the parent for all the
group - user-facing group which is the parent for all the
| scalar's drawing commands. Its matrix and options
| can be accessed from the [draw group] object (one
| per templatecanvas).
v
draw - the actual drawing command: rectangle, path, etc.
Each has its own matrix and options which can set
with messages to the corresponding [draw] object.
(draw - the actual drawing command: rectangle, path, etc.
or Each has its own matrix and options which can set
scelem with messages to the corresponding [draw] object.
or - ds arrays can nest arbitrarily deep. Scelem is for
group) data structure arrays. group is for more groups.
|
v
etc.
The tag "blankscalar" is for scalars that don't have a visual
representation, but maybe this can just be merged with "scalar"
......@@ -701,20 +755,30 @@ static void scalar_vis(t_gobj *z, t_glist *owner, int vis)
xscale, 0.0, 0.0, yscale, (int)glist_xtopixels(owner, basex),
(int)glist_ytopixels(owner, basey)
);
sys_vgui(".x%lx.c create group -tags {.dgroup%lx} "
sys_vgui(".x%lx.c create group -tags {.dgroup%lx.%lx} "
"-parent {.scalar%lx}\n",
glist_getcanvas(owner), x->sc_vec, x->sc_vec);
glist_getcanvas(owner), templatecanvas, x->sc_vec, x->sc_vec);
sys_vgui("pdtk_bind_scalar_mouseover "
".x%lx.c .x%lx.x%lx.template%lx {.x%lx}\n",
glist_getcanvas(owner), glist_getcanvas(owner),
owner, x->sc_vec, x);
}
/* warning: don't need--- have recursive func. */
for (y = templatecanvas->gl_list; y; y = y->g_next)
{
t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd);
if (!wb) continue;
(*wb->w_parentvisfn)(y, owner, x, x->sc_vec, template,
if (!wb)
{
/* check subpatches for more drawing commands. This
can be optimized to only search [group] subpatches */
if (pd_class(&y->g_pd) == canvas_class &&
((t_glist *)y)->gl_svg)
scalar_groupvis(x, owner, template,
(t_glist *)y, templatecanvas, vis);
continue;
}
(*wb->w_parentvisfn)(y, owner, 0, x, x->sc_vec, template,
basex, basey, vis);
}
if (!vis)
......@@ -750,6 +814,39 @@ void scalar_redraw(t_scalar *x, t_glist *glist)
//sys_queuegui(x, glist, scalar_doredraw);
}
int scalar_groupclick(struct _glist *groupcanvas,
t_word *data, t_template *template, t_scalar *sc,
t_array *ap, struct _glist *owner,
t_float xloc, t_float yloc, int xpix, int ypix,
int shift, int alt, int dbl, int doit, t_float basex, t_float basey)
{
int hit = 0;
t_gobj *y;
for (y = groupcanvas->gl_list; y; y = y->g_next)
{
if (pd_class(&y->g_pd) == canvas_class &&
((t_glist *)y)->gl_svg)
{
// fprintf(stderr, "fuck dolphins");
if (hit = scalar_groupclick((t_glist *)y, data, template, sc, ap,
owner, xloc, yloc, xpix, ypix,
shift, alt, dbl, doit, basex, basey))
{
return (hit);
}
}
t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd);
if (!wb) continue;
if (hit = (*wb->w_parentclickfn)(y, owner,
data, template, sc, ap, basex + xloc, basey + yloc,
xpix, ypix, shift, alt, dbl, doit))
{
return (hit);
}
}
return 0;
}
int scalar_doclick(t_word *data, t_template *template, t_scalar *sc,
t_array *ap, struct _glist *owner,
t_float xloc, t_float yloc, int xpix, int ypix,
......@@ -782,22 +879,27 @@ int scalar_doclick(t_word *data, t_template *template, t_scalar *sc,
basey = 0.0;
}
for (y = templatecanvas->gl_list; y; y = y->g_next)
{
hit = scalar_groupclick(templatecanvas, data, template, sc, ap,
owner, xloc, yloc, xpix, ypix,
shift, alt, dbl, doit, basex, basey);
return hit;
// for (y = templatecanvas->gl_list; y; y = y->g_next)
// {
//fprintf(stderr,"looking for template... %f %f %f %f %lx %lx\n",
// basex, basey, xloc, yloc, (t_int)owner, (t_int)data);
t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd);
if (!wb) continue;
if (hit = (*wb->w_parentclickfn)(y, owner,
data, template, sc, ap, basex + xloc, basey + yloc,
xpix, ypix, shift, alt, dbl, doit))
{
// t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd);
// if (!wb) continue;
// if (hit = (*wb->w_parentclickfn)(y, owner,
// data, template, sc, ap, basex + xloc, basey + yloc,
// xpix, ypix, shift, alt, dbl, doit))
// {
//fprintf(stderr," ...got it %f %f\n",
// basex + xloc, basey + yloc);
return (hit);
}
}
return (0);
// return (hit);
// }
// }
// return (0);
}
static int scalar_click(t_gobj *z, struct _glist *owner,
......
This diff is collapsed.
......@@ -2184,6 +2184,20 @@ void text_eraseborder(t_text *x, t_glist *glist, char *tag)
glist_eraseiofor(glist, x, tag);
}
static int compare_subpatch_selectors(t_atom *a, t_atom *b)
{
if (a[0].a_type == A_SYMBOL && b[0].a_type == A_SYMBOL)
{
return (!strcmp(a[0].a_w.w_symbol->s_name, "pd") &&
!strcmp(b[0].a_w.w_symbol->s_name, "pd"))
||
(!strcmp(a[0].a_w.w_symbol->s_name, "group") &&
!strcmp(b[0].a_w.w_symbol->s_name, "group"));
}
else
return 0;
}
/* change text; if T_OBJECT, remake it. */
void text_setto(t_text *x, t_glist *glist, char *buf, int bufsize, int pos)
......@@ -2205,11 +2219,8 @@ void text_setto(t_text *x, t_glist *glist, char *buf, int bufsize, int pos)
vec2 = binbuf_getvec(b);
/* special case: if pd subpatch is valid and its args change,
and its new name is valid, just pass the message on. */
if (x->te_pd == canvas_class && natom1 >= 1 && natom2 >= 1
&& vec1[0].a_type == A_SYMBOL
&& !strcmp(vec1[0].a_w.w_symbol->s_name, "pd")
&& vec2[0].a_type == A_SYMBOL
&& !strcmp(vec2[0].a_w.w_symbol->s_name, "pd"))
if (x->te_pd == canvas_class && natom1 >= 1 && natom2 >= 1 &&
compare_subpatch_selectors(vec1, vec2))
{
//fprintf(stderr,"setto canvas\n");
//first check if the contents have changed to see if there is
......
......@@ -11,7 +11,7 @@ extern "C" {
#define PD_MAJOR_VERSION 0
#define PD_MINOR_VERSION 42
#define PD_BUGFIX_VERSION 7
#define PD_TEST_VERSION "20140319"
#define PD_TEST_VERSION "20140402"
#define PDL2ORK
/* old name for "MSW" flag -- we have to take it for the sake of many old
......
......@@ -64,12 +64,12 @@ proc pdtk_drawimage_new {obj path canvasdir flags} {
}
}
proc pdtk_drawimage_vis {c x y obj tag seqno l2orktag1 l2orktag2 tag3} {
proc pdtk_drawimage_vis {c x y obj tag seqno l2orktag1 l2orktag2 tag3 drawtag} {
set img ::drawimage_${obj}
set len [llength [lsearch -glob -all [image names] ${img}*]]
if {$len < 1} {return}
if {$seqno >= $len || $seqno < 0} {set seqno [expr {$seqno % $len}]}
$c create pimage $x $y -image ${img}$seqno -tags [list $tag $l2orktag1 $l2orktag2] -parent $tag3
$c create pimage $x $y -image ${img}$seqno -tags [list $tag $l2orktag1 $l2orktag2 $drawtag] -parent $tag3
}
proc pdtk_drawimage_unvis {c tag} {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment