Commit de65f674 authored by Jonathan Wilkes's avatar Jonathan Wilkes
Browse files

add [event] class for canvas field

parent 30f8c6cf
......@@ -360,6 +360,13 @@ void canvasgop__clickhook(t_scalehandle *sh, int newstate);
void canvasgop__motionhook(t_scalehandle *sh,t_floatarg f1, t_floatarg f2);
extern void glist_setlastxy(t_glist *gl, int xval, int yval);
/* These globals are used to set state for the "canvas" field in a
struct. We try below to make sure they only get set for the toplevel
canvas, and then set them to NULL for everything else. */
t_symbol *canvas_field_templatesym; /* for "canvas" data type */
t_word *canvas_field_vec; /* for "canvas" data type */
t_gpointer *canvas_field_gp; /* parent for "canvas" data type */
/* make a new glist. It will either be a "root" canvas or else
it appears as a "text" object in another window (canvas_getcurrent()
tells us which.) */
......@@ -465,6 +472,16 @@ t_canvas *canvas_new(void *dummy, t_symbol *sel, int argc, t_atom *argv)
x->u_queue = canvas_undo_init(x);
//glist_setlastxy(x, 20, 20);
x->gl_templatesym = canvas_field_templatesym;
x->gl_vec = canvas_field_vec;
if (canvas_field_gp) gpointer_copy(canvas_field_gp, &x->gl_gp);
// unset the globals in case this was a canvas field
canvas_field_templatesym = NULL;
canvas_field_vec = NULL;
canvas_field_gp = NULL;
return(x);
}
......
......@@ -18,6 +18,10 @@ t_class *scalar_class;
void pd_doloadbang(void);
extern t_symbol *canvas_field_templatesym; /* for "canvas" data type */
extern t_word *canvas_field_vec; /* for "canvas" data type */
extern t_gpointer *canvas_field_gp; /* parent for "canvas" data type */
void word_init(t_word *data, t_template *template, t_gpointer *gp)
{
int i, nitems = template->t_n;
......@@ -36,6 +40,23 @@ void word_init(t_word *data, t_template *template, t_gpointer *gp)
}
else if (type == DT_LIST)
{
/* we feed these values to global vars so that we can
read them from inside canvas_new. This is very hacky,
but I couldn't figure out a better way to do it. */
canvas_field_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. */
canvas_field_vec = data;
/* Here too we're being dangerous-- I'm copying the gpointer
without recounting, and I'm not unsetting the one that's
part of the _glist struct (t_gpointer gl_gp). */
canvas_field_gp = gp;
/* copied from glob_evalfile... */
t_pd *x = 0;
/* even though binbuf_evalfile appears to take care of dspstate,
......@@ -62,17 +83,6 @@ void word_init(t_word *data, t_template *template, t_gpointer *gp)
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);
/* make the parent glist the parent of our canvas field */
wp->w_list->gl_owner = gp->gp_stub->gs_un.gs_glist;
......
......@@ -4149,9 +4149,10 @@ static int draw_click(t_gobj *z, t_glist *glist,
void draw_notify(t_canvas *x, t_symbol *s, int argc, t_atom *argv)
{
char canvas_field_namebuf[20];
t_symbol *canvas_field_event;
t_symbol *scalarsym = atom_getsymbolarg(0, argc--, argv++);
t_symbol *drawcommand_sym = atom_getsymbolarg(0, argc--, argv++);
t_symbol *event_name = atom_getsymbolarg(0, argc--, argv++);
t_scalar *sc;
t_object *ob = 0;
if (scalarsym->s_thing)
......@@ -4161,6 +4162,20 @@ void draw_notify(t_canvas *x, t_symbol *s, int argc, t_atom *argv)
error("draw_notify: can't get scalar from symbol");
return;
}
/* Generate the symbol that would be bound by any [event] inside
a canvas field. If there's any in existence, forward the event
notification. pd_bind takes care of the details of this-- if
there are multiple [event] objects it will dispatch to each */
sprintf(canvas_field_namebuf, "%lx_event", (long unsigned int)sc->sc_vec);
canvas_field_event = gensym(canvas_field_namebuf);
t_pd *target = canvas_field_event->s_thing;
if (target)
pd_forwardmess(target, argc, argv);
/* need to revisit popping this off the args, it's a little confusing... */
t_symbol *event_name = atom_getsymbolarg(0, argc--, argv++);
if (drawcommand_sym->s_thing)
{
t_pd *drawcommand = (t_pd *)drawcommand_sym->s_thing;
......@@ -4406,6 +4421,50 @@ static void draw_setup(void)
gensym("y2"), A_GIMME, 0);
}
/* ------------------------------ event --------------------------------- */
/* This is a very simple class used to dispatch events inside a
canvas field. */
t_class *event_class;
typedef struct _event
{
t_object x_obj;
t_symbol *x_bindsym;
} t_event;
static void event_anything(t_event *x, t_symbol *s, int argc, t_atom *argv)
{
outlet_anything(x->x_obj.ob_outlet, s, argc, argv);
}
static void *event_new(void)
{
char namebuf[20];
t_event *x = (t_event *)pd_new(event_class);
t_canvas *c = canvas_getcurrent();
if (c->gl_vec)
{
sprintf(namebuf, "%lx_event", (long unsigned int)c->gl_vec);
x->x_bindsym = gensym(namebuf);
pd_bind(&x->x_obj.ob_pd, x->x_bindsym);
}
outlet_new(&x->x_obj, &s_anything);
return (x);
}
static void event_free(t_event *x)
{
pd_unbind(&x->x_obj.ob_pd, x->x_bindsym);
}
void event_setup(void)
{
event_class = class_new(gensym("event"), (t_newmethod)event_new,
(t_method)event_free, sizeof(t_event), 0, 0);
class_addanything(event_class, event_anything);
}
/* ---------------- curves and polygons (joined segments) ---------------- */
/*
......@@ -7749,6 +7808,7 @@ void g_template_setup(void)
gtemplate_setup();
curve_setup();
draw_setup();
event_setup();
plot_setup();
drawnumber_setup();
drawsymbol_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