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
struct _scalehandle *x_handle;
struct _scalehandle *x_mhandle;
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_gpointer gl_gp; /* parent for "canvas" data type */
};
#define gl_gobj gl_obj.te_g
......
......@@ -2307,6 +2307,8 @@ t_gobj *canvas_findhitbox(t_canvas *x, int xpos, int ypos,
return (rval);
}
extern int scalar_hascanvasfield(t_scalar *x);
/* 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)
{
......@@ -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;
int canprop, canopen, isobject;
t_gobj *y = NULL;
int x1, y1, x2, y2;
int x1, y1, x2, y2, scalar_has_canvas = 0;
if (x->gl_editor->e_selection)
{
glist_noselect(x);
......@@ -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)))
/*&& !canvas_isabstraction( ((t_glist*)y) )*/ );
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)
{
isobject = 1;
......
......@@ -18,10 +18,11 @@ t_class *scalar_class;
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;
t_dataslot *datatypes = template->t_vec;
t_word *wp = data;
for (i = 0; i < nitems; i++, datatypes++, wp++)
{
int type = datatypes->ds_type;
......@@ -60,11 +61,23 @@ void word_init(t_word *wp, t_template *template, t_gpointer *gp)
glob_setfilename(0, &s_, &s_);
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)
{
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.
Why?
......@@ -242,12 +255,27 @@ int template_cancreate(t_template *template)
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
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
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. */
t_scalar *scalar_new(t_glist *owner, t_symbol *templatesym)
{
t_scalar *x;
......@@ -1197,6 +1225,11 @@ static void scalar_save(t_gobj *z, t_binbuf *b)
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)
{
t_scalar *x = (t_scalar *)z;
......@@ -1256,6 +1289,8 @@ void g_scalar_setup(void)
CLASS_GOBJ, 0);
class_addmethod(scalar_class, (t_method)scalar_mouseover,
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_setsavefn(scalar_class, scalar_save);
class_setpropertiesfn(scalar_class, scalar_properties);
......
......@@ -13,6 +13,7 @@ getsize - get the size of an array
setsize - change the size of an array
append - add an element to a list
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)
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 ------------------- */
void g_traversal_setup(void)
......@@ -1317,4 +1424,5 @@ void g_traversal_setup(void)
setsize_setup();
append_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