Commit 710d3e63 authored by Jonathan Wilkes's avatar Jonathan Wilkes
Browse files

more work on canvas field for data structures

parent 61971b16
...@@ -223,8 +223,9 @@ struct _glist ...@@ -223,8 +223,9 @@ struct _glist
struct _scalehandle *x_handle; struct _scalehandle *x_handle;
struct _scalehandle *x_mhandle; struct _scalehandle *x_mhandle;
t_pd *gl_svg; t_pd *gl_svg;
t_symbol *gl_templatename; /* for "canvas" data type */ t_symbol *gl_templatesym; /* for "canvas" data type */
t_word *gl_vec; /* for "canvas" data type */ t_word *gl_vec; /* for "canvas" data type */
t_gpointer gl_gp; /* parent for "canvas" data type */
}; };
#define gl_gobj gl_obj.te_g #define gl_gobj gl_obj.te_g
......
...@@ -2307,6 +2307,8 @@ t_gobj *canvas_findhitbox(t_canvas *x, int xpos, int ypos, ...@@ -2307,6 +2307,8 @@ t_gobj *canvas_findhitbox(t_canvas *x, int xpos, int ypos,
return (rval); return (rval);
} }
extern int scalar_hascanvasfield(t_scalar *x);
/* right-clicking on a canvas object pops up a menu. */ /* right-clicking on a canvas object pops up a menu. */
static void canvas_rightclick(t_canvas *x, int xpos, int ypos, t_gobj *y_sel) static void canvas_rightclick(t_canvas *x, int xpos, int ypos, t_gobj *y_sel)
{ {
...@@ -2314,7 +2316,7 @@ static void canvas_rightclick(t_canvas *x, int xpos, int ypos, t_gobj *y_sel) ...@@ -2314,7 +2316,7 @@ static void canvas_rightclick(t_canvas *x, int xpos, int ypos, t_gobj *y_sel)
if (x->gl_editor->e_onmotion != MA_NONE) return; if (x->gl_editor->e_onmotion != MA_NONE) return;
int canprop, canopen, isobject; int canprop, canopen, isobject;
t_gobj *y = NULL; t_gobj *y = NULL;
int x1, y1, x2, y2; int x1, y1, x2, y2, scalar_has_canvas = 0;
if (x->gl_editor->e_selection) if (x->gl_editor->e_selection)
{ {
glist_noselect(x); glist_noselect(x);
...@@ -2344,6 +2346,14 @@ static void canvas_rightclick(t_canvas *x, int xpos, int ypos, t_gobj *y_sel) ...@@ -2344,6 +2346,14 @@ static void canvas_rightclick(t_canvas *x, int xpos, int ypos, t_gobj *y_sel)
canprop = (!y || (y && class_getpropertiesfn(pd_class(&y->g_pd))) canprop = (!y || (y && class_getpropertiesfn(pd_class(&y->g_pd)))
/*&& !canvas_isabstraction( ((t_glist*)y) )*/ ); /*&& !canvas_isabstraction( ((t_glist*)y) )*/ );
canopen = (y && zgetfn(&y->g_pd, gensym("menu-open"))); canopen = (y && zgetfn(&y->g_pd, gensym("menu-open")));
/* we add an extra check for scalars to enable the "Open" button
if they happen to have a canvas field inside them. */
if (pd_class(&y->g_pd) == scalar_class)
{
if (scalar_hascanvasfield((t_scalar *)y))
scalar_has_canvas = 1;
canopen = scalar_has_canvas;
}
if (y || x->gl_editor->e_selection) if (y || x->gl_editor->e_selection)
{ {
isobject = 1; isobject = 1;
......
...@@ -18,10 +18,11 @@ t_class *scalar_class; ...@@ -18,10 +18,11 @@ t_class *scalar_class;
void pd_doloadbang(void); void pd_doloadbang(void);
void word_init(t_word *wp, t_template *template, t_gpointer *gp) void word_init(t_word *data, t_template *template, t_gpointer *gp)
{ {
int i, nitems = template->t_n; int i, nitems = template->t_n;
t_dataslot *datatypes = template->t_vec; t_dataslot *datatypes = template->t_vec;
t_word *wp = data;
for (i = 0; i < nitems; i++, datatypes++, wp++) for (i = 0; i < nitems; i++, datatypes++, wp++)
{ {
int type = datatypes->ds_type; int type = datatypes->ds_type;
...@@ -60,11 +61,23 @@ void word_init(t_word *wp, t_template *template, t_gpointer *gp) ...@@ -60,11 +61,23 @@ void word_init(t_word *wp, t_template *template, t_gpointer *gp)
glob_setfilename(0, &s_, &s_); glob_setfilename(0, &s_, &s_);
wp->w_list = canvas_getcurrent(); wp->w_list = canvas_getcurrent();
wp->w_list->gl_templatesym = template->t_sym;
/* this is bad-- we're storing a reference to a position in
a dynamically allocated byte array when realloc can potentially
move this data. Essentially, we're depending on gcc to never
move it, which is a bad assumption. Unfortunately gpointers
do the same thing, and I haven't heard back from Miller yet
on how he plans to deal with this problem. Hopefully that same
solution will be usable here. */
wp->w_list->gl_vec = data;
/* Here too we're being dangerous-- I'm not unsetting this
gpointer yet. */
gpointer_copy(gp, &wp->w_list->gl_gp);
while ((x != s__X.s_thing) && s__X.s_thing) while ((x != s__X.s_thing) && s__X.s_thing)
{ {
x = s__X.s_thing; x = s__X.s_thing;
vmess(x, gensym("pop"), "i", 1); vmess(x, gensym("pop"), "i", 0);
} }
/* oops, can't actually do a loadbang here. /* oops, can't actually do a loadbang here.
Why? Why?
...@@ -242,12 +255,27 @@ int template_cancreate(t_template *template) ...@@ -242,12 +255,27 @@ int template_cancreate(t_template *template)
return (template_check_array_fields(0, template) == 1); return (template_check_array_fields(0, template) == 1);
} }
int scalar_hascanvasfield(t_scalar *x)
{
t_template *template = template_findbyname(x->sc_template);
if (template)
{
int i, nitems = template->t_n;
t_dataslot *datatypes = template->t_vec;
for (i = 0; i < nitems; i++, datatypes++)
{
if (datatypes->ds_type == DT_LIST)
return 1;
}
}
return 0;
}
/* make a new scalar and add to the glist. We create a "gp" here which /* make a new scalar and add to the glist. We create a "gp" here which
will be used for array items to point back here. This gp doesn't do will be used for array items to point back here. This gp doesn't do
reference counting or "validation" updates though; the parent won't go away reference counting or "validation" updates though; the parent won't go away
without the contained arrays going away too. The "gp" is copied out without the contained arrays going away too. The "gp" is copied out
by value in the word_init() routine so we can throw our copy away. */ by value in the word_init() routine so we can throw our copy away. */
t_scalar *scalar_new(t_glist *owner, t_symbol *templatesym) t_scalar *scalar_new(t_glist *owner, t_symbol *templatesym)
{ {
t_scalar *x; t_scalar *x;
...@@ -1197,6 +1225,11 @@ static void scalar_save(t_gobj *z, t_binbuf *b) ...@@ -1197,6 +1225,11 @@ static void scalar_save(t_gobj *z, t_binbuf *b)
binbuf_free(b2); binbuf_free(b2);
} }
static void scalar_menuopen(t_scalar *x)
{
post("tried to open a thing");
}
static void scalar_properties(t_gobj *z, struct _glist *owner) static void scalar_properties(t_gobj *z, struct _glist *owner)
{ {
t_scalar *x = (t_scalar *)z; t_scalar *x = (t_scalar *)z;
...@@ -1256,6 +1289,8 @@ void g_scalar_setup(void) ...@@ -1256,6 +1289,8 @@ void g_scalar_setup(void)
CLASS_GOBJ, 0); CLASS_GOBJ, 0);
class_addmethod(scalar_class, (t_method)scalar_mouseover, class_addmethod(scalar_class, (t_method)scalar_mouseover,
gensym("mouseover"), A_FLOAT, A_NULL); gensym("mouseover"), A_FLOAT, A_NULL);
class_addmethod(scalar_class, (t_method)scalar_menuopen,
gensym("menu-open"), 0);
class_setwidget(scalar_class, &scalar_widgetbehavior); class_setwidget(scalar_class, &scalar_widgetbehavior);
class_setsavefn(scalar_class, scalar_save); class_setsavefn(scalar_class, scalar_save);
class_setpropertiesfn(scalar_class, scalar_properties); class_setpropertiesfn(scalar_class, scalar_properties);
......
...@@ -13,6 +13,7 @@ getsize - get the size of an array ...@@ -13,6 +13,7 @@ getsize - get the size of an array
setsize - change the size of an array setsize - change the size of an array
append - add an element to a list append - add an element to a list
sublist - get a pointer into a list which is an element of another scalar sublist - get a pointer into a list which is an element of another scalar
field - get numeric/symbolic field while within a canvas field
*/ */
...@@ -1305,6 +1306,112 @@ static void sublist_setup(void) ...@@ -1305,6 +1306,112 @@ static void sublist_setup(void)
class_addpointer(sublist_class, sublist_pointer); class_addpointer(sublist_class, sublist_pointer);
} }
/* ---------------------- field ----------------------------- */
static t_class *field_class;
typedef struct _field
{
t_object x_obj;
t_symbol *x_s;
t_template *x_template;
t_canvas *x_canvas;
} t_field;
static void *field_new(t_symbol *s)
{
t_field *x = (t_field *)pd_new(field_class);
x->x_s = s;
x->x_canvas = canvas_getcurrent();
// do some error checking here
x->x_template = template_findbyname(x->x_canvas->gl_templatesym);
outlet_new(&x->x_obj, &s_list);
return (x);
}
static void field_set(t_field *x, t_symbol *s)
{
x->x_s = s;
}
static void field_bang(t_field *x)
{
post("sanity is %d", x->x_canvas->sanity);
t_word *vec = x->x_canvas->gl_vec;
t_template *template = x->x_template;
t_symbol *fieldsym = x->x_s;
int onset, type;
t_symbol *arraytype;
if (template_find_field(template, fieldsym, &onset, &type, &arraytype))
{
if (type == DT_FLOAT)
outlet_float(x->x_obj.ob_outlet,
*(t_float *)(((char *)vec) + onset));
else if (type == DT_SYMBOL)
outlet_symbol(x->x_obj.ob_outlet,
*(t_symbol **)(((char *)vec)+ onset));
else pd_error(x, "field: %s.%s is not a number or symbol",
template->t_sym->s_name, fieldsym->s_name);
}
else pd_error(x, "field: %s.%s: no such field",
template->t_sym->s_name, fieldsym->s_name);
}
static void field_setvalue(t_field *x, t_symbol *s, int argc, t_atom *argv)
{
t_template *template = x->x_template;
t_word *vec = x->x_canvas->gl_vec;
t_gpointer *gp = &x->x_canvas->gl_gp;
t_gstub *gs = gp->gp_stub;
int onset, type;
t_symbol *arraytype, *fieldsym = x->x_s;
if (argc)
{
if (argv->a_type == A_FLOAT)
template_setfloat(template, fieldsym, vec,
atom_getfloatarg(0, argc, argv), 1);
else if (argv->a_type == A_SYMBOL)
template_setsymbol(template, fieldsym, vec,
atom_getsymbolarg(0, argc, argv), 1);
else pd_error(x, "field: incoming value must be float or symbol");
}
if (gp->gp_stub->gs_which == GP_GLIST)
scalar_configure((t_scalar *)(gp->gp_un.gp_gobj), gs->gs_un.gs_glist);
else
{
t_array *owner_array = gs->gs_un.gs_array;
while (owner_array->a_gp.gp_stub->gs_which == GP_ARRAY)
owner_array = owner_array->a_gp.gp_stub->gs_un.gs_array;
scalar_redraw((t_scalar *)(owner_array->a_gp.gp_un.gp_gobj),
owner_array->a_gp.gp_stub->gs_un.gs_glist);
}
}
static void field_symbol(t_field *x, t_symbol *s)
{
t_atom at[1];
SETSYMBOL(at, s);
field_setvalue(x, gensym("symbol"), 1, at);
}
static void field_float(t_field *x, t_floatarg f)
{
t_atom at[1];
SETFLOAT(at, f);
field_setvalue(x, gensym("float"), 1, at);
}
static void field_setup(void)
{
field_class = class_new(gensym("field"), (t_newmethod)field_new,
0, sizeof(t_field), 0, A_DEFSYM, 0);
class_addfloat(field_class, field_float);
class_addsymbol(field_class, field_symbol);
class_addbang(field_class, field_bang);
class_addmethod(field_class, (t_method)field_set, gensym("set"),
A_SYMBOL, 0);
}
/* ----------------- setup function ------------------- */ /* ----------------- setup function ------------------- */
void g_traversal_setup(void) void g_traversal_setup(void)
...@@ -1317,4 +1424,5 @@ void g_traversal_setup(void) ...@@ -1317,4 +1424,5 @@ void g_traversal_setup(void)
setsize_setup(); setsize_setup();
append_setup(); append_setup();
sublist_setup(); sublist_setup();
field_setup();
} }
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