From 57045df5fe3ec557e57dc7434ac1a07b5521bffc Mon Sep 17 00:00:00 2001 From: Guenter Geiger Date: Mon, 29 Jul 2002 17:06:19 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r58, which included commits to RCS files with non-trunk default branches. svn path=/trunk/; revision=59 --- pd/src/x_gui.c | 377 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 377 insertions(+) create mode 100644 pd/src/x_gui.c (limited to 'pd/src/x_gui.c') diff --git a/pd/src/x_gui.c b/pd/src/x_gui.c new file mode 100644 index 00000000..03e1b0dd --- /dev/null +++ b/pd/src/x_gui.c @@ -0,0 +1,377 @@ +/* Copyright (c) 1997-2000 Miller Puckette. +* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ + +/* dialogs. LATER, deal with the situation where the object goes +away before the panel does... */ + +#include "m_pd.h" +#include +#include +#ifdef UNIX +#include +#endif + +/* --------------------- graphics responder ---------------- */ + +/* make one of these if you want to put up a dialog window but want to be +protected from getting deleted and then having the dialog call you back. In +this design the calling object doesn't have to keep the address of the dialog +window around; instead we keep a list of all open dialogs. Any object that +might have dialogs, when it is deleted, simply checks down the dialog window +list and breaks off any dialogs that might later have sent messages to it. +Only when the dialog window itself closes do we delete the gfxstub object. */ + +static t_class *gfxstub_class; + +typedef struct _gfxstub +{ + t_pd x_pd; + t_pd *x_owner; + void *x_key; + t_symbol *x_sym; + struct _gfxstub *x_next; +} t_gfxstub; + +static t_gfxstub *gfxstub_list; + + /* create a new one. the "key" is an address by which the owner + will identify it later; if the owner only wants one dialog, this + could just be a pointer to the owner itself. The string "cmd" + is a TK command to create the dialog, with "%s" embedded in + it so we can provide a name by which the GUI can send us back + messages; e.g., "pdtk_canvas_dofont %s 10". */ + +void gfxstub_new(t_pd *owner, void *key, const char *cmd) +{ + char buf[MAXPDSTRING]; + char namebuf[80]; + t_gfxstub *x; + t_symbol *s; + /* if any exists with matching key, no need to make a + new one; just tell tk to send it front. */ + for (x = gfxstub_list; x; x = x->x_next) + { + if (x->x_key == key) + { + sys_vgui("raise .gfxstub%x\n", x); + sys_vgui("focus .gfxstub%x\n", x); + return; + } + } + if (strlen(cmd) + 84 > MAXPDSTRING) + return; + x = (t_gfxstub *)pd_new(gfxstub_class); + sprintf(namebuf, ".gfxstub%x", (t_int)x); + + s = gensym(namebuf); + pd_bind(&x->x_pd, s); + x->x_owner = owner; + x->x_sym = s; + x->x_key = key; + x->x_next = gfxstub_list; + gfxstub_list = x; + sprintf(buf, cmd, s->s_name); + sys_gui(buf); +} + +static void gfxstub_offlist(t_gfxstub *x) +{ + t_gfxstub *y1, *y2; + if (gfxstub_list == x) + gfxstub_list = x->x_next; + else for (y1 = gfxstub_list; y2 = y1->x_next; y1 = y2) + if (y2 == x) + { + y1->x_next = y2->x_next; + break; + } +} + + /* if the owner disappears, we still may have to stay around until our + dialog window signs off. Anyway we can now tell the GUI to destroy the + window. */ +void gfxstub_deleteforkey(void *key) +{ + t_gfxstub *y; + int didit = 1; + while (didit) + { + didit = 0; + for (y = gfxstub_list; y; y = y->x_next) + { + if (y->x_key == key) + { + sys_vgui("destroy .gfxstub%x\n", y); + y->x_owner = 0; + gfxstub_offlist(y); + didit = 1; + break; + } + } + } +} + +/* --------- pd messages for gfxstub (these come from the GUI) ---------- */ + + /* "cancel" to request that we close the dialog window. */ +static void gfxstub_cancel(t_gfxstub *x) +{ + gfxstub_deleteforkey(x->x_key); +} + + /* "signoff" comes from the GUI to say the dialog window closed. */ +static void gfxstub_signoff(t_gfxstub *x) +{ + gfxstub_offlist(x); + pd_free(&x->x_pd); +} + +static t_binbuf *gfxstub_binbuf; + + /* a series of "data" messages rebuilds a scalar */ +static void gfxstub_data(t_gfxstub *x, t_symbol *s, int argc, t_atom *argv) +{ + if (!gfxstub_binbuf) + gfxstub_binbuf = binbuf_new(); + binbuf_add(gfxstub_binbuf, argc, argv); + binbuf_addsemi(gfxstub_binbuf); +} + /* the "end" message terminates rebuilding the scalar */ +static void gfxstub_end(t_gfxstub *x) +{ + canvas_dataproperties((t_canvas *)x->x_owner, + (t_scalar *)x->x_key, gfxstub_binbuf); + binbuf_free(gfxstub_binbuf); + gfxstub_binbuf = 0; +} + + /* anything else is a message from the dialog window to the owner; + just forward it. */ +static void gfxstub_anything(t_gfxstub *x, t_symbol *s, int argc, t_atom *argv) +{ + if (x->x_owner) + pd_typedmess(x->x_owner, s, argc, argv); +} + +static void gfxstub_free(t_gfxstub *x) +{ + pd_unbind(&x->x_pd, x->x_sym); +} + +static void gfxstub_setup(void) +{ + gfxstub_class = class_new(gensym("gfxstub"), (t_newmethod)gfxstub_new, + (t_method)gfxstub_free, + sizeof(t_gfxstub), CLASS_PD, 0); + class_addanything(gfxstub_class, gfxstub_anything); + class_addmethod(gfxstub_class, (t_method)gfxstub_signoff, + gensym("signoff"), 0); + class_addmethod(gfxstub_class, (t_method)gfxstub_data, + gensym("data"), A_GIMME, 0); + class_addmethod(gfxstub_class, (t_method)gfxstub_end, + gensym("end"), 0); + class_addmethod(gfxstub_class, (t_method)gfxstub_cancel, + gensym("cancel"), 0); +} + +/* -------------------------- openpanel ------------------------------ */ + +static t_class *openpanel_class; + +typedef struct _openpanel +{ + t_object x_obj; + t_symbol *x_s; +} t_openpanel; + +static void *openpanel_new(void) +{ + char buf[50]; + t_openpanel *x = (t_openpanel *)pd_new(openpanel_class); + sprintf(buf, "d%x", (t_int)x); + x->x_s = gensym(buf); + pd_bind(&x->x_obj.ob_pd, x->x_s); + outlet_new(&x->x_obj, &s_symbol); + return (x); +} + +static void openpanel_bang(t_openpanel *x) +{ + sys_vgui("pdtk_openpanel %s\n", x->x_s->s_name); +} + +static void openpanel_symbol(t_openpanel *x, t_symbol *s) +{ + outlet_symbol(x->x_obj.ob_outlet, s); +} + +static void openpanel_free(t_openpanel *x) +{ + pd_unbind(&x->x_obj.ob_pd, x->x_s); +} + +static void openpanel_setup(void) +{ + openpanel_class = class_new(gensym("openpanel"), + (t_newmethod)openpanel_new, (t_method)openpanel_free, + sizeof(t_openpanel), 0, A_DEFFLOAT, 0); + class_addbang(openpanel_class, openpanel_bang); + class_addsymbol(openpanel_class, openpanel_symbol); +} + +/* -------------------------- savepanel ------------------------------ */ + +static t_class *savepanel_class; + +typedef struct _savepanel +{ + t_object x_obj; + t_symbol *x_s; +} t_savepanel; + +static void *savepanel_new(void) +{ + char buf[50]; + t_savepanel *x = (t_savepanel *)pd_new(savepanel_class); + sprintf(buf, "d%x", (t_int)x); + x->x_s = gensym(buf); + pd_bind(&x->x_obj.ob_pd, x->x_s); + outlet_new(&x->x_obj, &s_symbol); + return (x); +} + +static void savepanel_bang(t_savepanel *x) +{ + sys_vgui("pdtk_savepanel %s\n", x->x_s->s_name); +} + +static void savepanel_symbol(t_savepanel *x, t_symbol *s) +{ + outlet_symbol(x->x_obj.ob_outlet, s); +} + +static void savepanel_free(t_savepanel *x) +{ + pd_unbind(&x->x_obj.ob_pd, x->x_s); +} + +static void savepanel_setup(void) +{ + savepanel_class = class_new(gensym("savepanel"), + (t_newmethod)savepanel_new, (t_method)savepanel_free, + sizeof(t_savepanel), 0, A_DEFFLOAT, 0); + class_addbang(savepanel_class, savepanel_bang); + class_addsymbol(savepanel_class, savepanel_symbol); +} + +/* ---------------------- key and its relatives ------------------ */ + +static t_symbol *key_sym, *keyup_sym, *keyname_sym; +static t_class *key_class, *keyup_class, *keyname_class; + +typedef struct _key +{ + t_object x_obj; +} t_key; + +static void *key_new( void) +{ + t_key *x = (t_key *)pd_new(key_class); + outlet_new(&x->x_obj, &s_float); + pd_bind(&x->x_obj.ob_pd, key_sym); + return (x); +} + +static void key_float(t_key *x, t_floatarg f) +{ + outlet_float(x->x_obj.ob_outlet, f); +} + +static void key_free(t_key *x) +{ + pd_unbind(&x->x_obj.ob_pd, key_sym); +} + +typedef struct _keyup +{ + t_object x_obj; +} t_keyup; + +static void *keyup_new( void) +{ + t_keyup *x = (t_keyup *)pd_new(keyup_class); + outlet_new(&x->x_obj, &s_float); + pd_bind(&x->x_obj.ob_pd, keyup_sym); + return (x); +} + +static void keyup_float(t_keyup *x, t_floatarg f) +{ + outlet_float(x->x_obj.ob_outlet, f); +} + +static void keyup_free(t_keyup *x) +{ + pd_unbind(&x->x_obj.ob_pd, keyup_sym); +} + +typedef struct _keyname +{ + t_object x_obj; + t_outlet *x_outlet1; + t_outlet *x_outlet2; +} t_keyname; + +static void *keyname_new( void) +{ + t_keyname *x = (t_keyname *)pd_new(keyname_class); + x->x_outlet1 = outlet_new(&x->x_obj, &s_float); + x->x_outlet2 = outlet_new(&x->x_obj, &s_symbol); + pd_bind(&x->x_obj.ob_pd, keyname_sym); + return (x); +} + +static void keyname_list(t_keyname *x, t_symbol *s, int ac, t_atom *av) +{ + outlet_symbol(x->x_outlet2, atom_getsymbolarg(1, ac, av)); + outlet_float(x->x_outlet1, atom_getfloatarg(0, ac, av)); +} + +static void keyname_free(t_keyname *x) +{ + pd_unbind(&x->x_obj.ob_pd, keyname_sym); +} + +static void key_setup(void) +{ + key_class = class_new(gensym("key"), + (t_newmethod)key_new, (t_method)key_free, + sizeof(t_key), CLASS_NOINLET, 0); + class_addfloat(key_class, key_float); + key_sym = gensym("#key"); + + keyup_class = class_new(gensym("keyup"), + (t_newmethod)keyup_new, (t_method)keyup_free, + sizeof(t_keyup), CLASS_NOINLET, 0); + class_addfloat(keyup_class, keyup_float); + keyup_sym = gensym("#keyup"); + class_sethelpsymbol(keyup_class, gensym("key")); + + keyname_class = class_new(gensym("keyname"), + (t_newmethod)keyname_new, (t_method)keyname_free, + sizeof(t_keyname), CLASS_NOINLET, 0); + class_addlist(keyname_class, keyname_list); + keyname_sym = gensym("#keyname"); + class_sethelpsymbol(keyname_class, gensym("key")); +} + +/* -------------------------- setup routine ------------------------------ */ + +void x_gui_setup(void) +{ + gfxstub_setup(); + openpanel_setup(); + savepanel_setup(); + key_setup(); +} -- cgit v1.2.1