aboutsummaryrefslogtreecommitdiff
path: root/pd/src/x_gui.c
diff options
context:
space:
mode:
authorGuenter Geiger <ggeiger@users.sourceforge.net>2002-07-29 17:06:19 +0000
committerGuenter Geiger <ggeiger@users.sourceforge.net>2002-07-29 17:06:19 +0000
commit57045df5fe3ec557e57dc7434ac1a07b5521bffc (patch)
tree7174058b41b73c808107c7090d9a4e93ee202341 /pd/src/x_gui.c
parentda38b3424229e59f956252c3d89895e43e84e278 (diff)
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
Diffstat (limited to 'pd/src/x_gui.c')
-rw-r--r--pd/src/x_gui.c377
1 files changed, 377 insertions, 0 deletions
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 <stdio.h>
+#include <string.h>
+#ifdef UNIX
+#include <unistd.h>
+#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();
+}