aboutsummaryrefslogtreecommitdiff
path: root/pddp/pddplink.c
diff options
context:
space:
mode:
authorN.N. <krzyszcz@users.sourceforge.net>2005-05-30 09:29:26 +0000
committerN.N. <krzyszcz@users.sourceforge.net>2005-05-30 09:29:26 +0000
commitaebe147ae46e27127faa5c9d777de6b9ab822cc9 (patch)
tree1885dbe1bd120a52b083679e89343c594128ed32 /pddp/pddplink.c
parentb4eb41d8deb2db9fd5182e6858484edff33a4d96 (diff)
toxy alpha18 and pddp alpha2 (see notes.txt for toxy, pddp and shared)
svn path=/trunk/externals/miXed/; revision=3094
Diffstat (limited to 'pddp/pddplink.c')
-rw-r--r--pddp/pddplink.c304
1 files changed, 284 insertions, 20 deletions
diff --git a/pddp/pddplink.c b/pddp/pddplink.c
index d60a90a..d746bbd 100644
--- a/pddp/pddplink.c
+++ b/pddp/pddplink.c
@@ -2,6 +2,10 @@
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+/* This is a prototype of an active comment. It might be replaced with
+ a new core object type, T_LINK (te_type bitfield would have to be
+ extended then). */
+
#include <stdio.h>
#include <string.h>
#include "m_pd.h"
@@ -21,6 +25,10 @@ typedef struct _pddplink
t_object x_ob;
t_glist *x_glist;
int x_isboxed;
+ char *x_vistext;
+ int x_vissize;
+ int x_vislength;
+ int x_rtextactive;
t_symbol *x_dirsym;
t_symbol *x_ulink;
t_atom x_openargs[2];
@@ -29,6 +37,117 @@ typedef struct _pddplink
} t_pddplink;
static t_class *pddplink_class;
+static t_class *pddplinkbox_class;
+
+/* Code that might be merged back to g_text.c starts here: */
+
+static void pddplink_getrect(t_gobj *z, t_glist *glist,
+ int *xp1, int *yp1, int *xp2, int *yp2)
+{
+ t_pddplink *x = (t_pddplink *)z;
+ int width, height;
+ float x1, y1, x2, y2;
+ if (glist->gl_editor && glist->gl_editor->e_rtext)
+ {
+ if (x->x_rtextactive)
+ {
+ t_rtext *y = glist_findrtext(glist, (t_text *)x);
+ width = rtext_width(y);
+ height = rtext_height(y) - 2;
+ }
+ else
+ {
+ int font = glist_getfont(glist);
+ width = x->x_vislength * sys_fontwidth(font) + 2;
+ height = sys_fontheight(font) + 2;
+ }
+ }
+ else width = height = 10;
+ x1 = text_xpix((t_text *)x, glist);
+ y1 = text_ypix((t_text *)x, glist);
+ x2 = x1 + width;
+ y2 = y1 + height;
+ y1 += 1;
+ *xp1 = x1;
+ *yp1 = y1;
+ *xp2 = x2;
+ *yp2 = y2;
+}
+
+static void pddplink_displace(t_gobj *z, t_glist *glist, int dx, int dy)
+{
+ t_text *t = (t_text *)z;
+ t->te_xpix += dx;
+ t->te_ypix += dy;
+ if (glist_isvisible(glist))
+ {
+ t_rtext *y = glist_findrtext(glist, t);
+ rtext_displace(y, dx, dy);
+ }
+}
+
+static void pddplink_select(t_gobj *z, t_glist *glist, int state)
+{
+ t_pddplink *x = (t_pddplink *)z;
+ t_rtext *y = glist_findrtext(glist, (t_text *)x);
+ rtext_select(y, state);
+ if (glist_isvisible(glist) && glist->gl_havewindow)
+ {
+ if (state)
+ sys_vgui(".x%lx.c itemconfigure %s -fill blue\n",
+ glist, rtext_gettag(y));
+ else
+ sys_vgui(".x%lx.c itemconfigure %s -text {%s} -fill magenta\n",
+ glist, rtext_gettag(y), x->x_vistext);
+ }
+}
+
+static void pddplink_activate(t_gobj *z, t_glist *glist, int state)
+{
+ t_pddplink *x = (t_pddplink *)z;
+ t_rtext *y = glist_findrtext(glist, (t_text *)x);
+ rtext_activate(y, state);
+ x->x_rtextactive = state;
+}
+
+static void pddplink_vis(t_gobj *z, t_glist *glist, int vis)
+{
+ t_pddplink *x = (t_pddplink *)z;
+ if (vis)
+ {
+ if (glist->gl_havewindow)
+ {
+ t_rtext *y = glist_findrtext(glist, (t_text *)x);
+ rtext_draw(y);
+ sys_vgui(".x%lx.c itemconfigure %s -text {%s} -fill magenta\n",
+ glist, rtext_gettag(y), x->x_vistext);
+ }
+ }
+ else
+ {
+ if (glist->gl_havewindow)
+ {
+ t_rtext *y = glist_findrtext(glist, (t_text *)x);
+ rtext_erase(y);
+ }
+ }
+}
+
+static int pddplink_wbclick(t_gobj *z, t_glist *glist, int xpix, int ypix,
+ int shift, int alt, int dbl, int doit);
+
+static t_widgetbehavior pddplink_widgetbehavior =
+{
+ pddplink_getrect,
+ pddplink_displace,
+ pddplink_select,
+ pddplink_activate,
+ 0,
+ pddplink_vis,
+ pddplink_wbclick,
+};
+
+/* Code that might be merged back to g_text.c ends here. */
/* FIXME need access to glob_pdobject... */
static t_pd *pddplink_pdtarget(t_pddplink *x)
@@ -66,6 +185,98 @@ static void pddplink_click(t_pddplink *x, t_floatarg xpos, t_floatarg ypos,
x->x_ishit = 0;
}
+static int pddplink_wbclick(t_gobj *z, t_glist *glist, int xpix, int ypix,
+ int shift, int alt, int dbl, int doit)
+{
+ if (doit)
+ pddplink_click((t_pddplink *)z, (t_floatarg)xpix, (t_floatarg)ypix,
+ (t_floatarg)shift, 0, (t_floatarg)alt);
+ return (1);
+}
+
+static int pddplink_isoption(char *name)
+{
+ if (*name == '-')
+ {
+ char c = name[1];
+ return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
+ }
+ else return (0);
+}
+
+static t_symbol *pddplink_nextsymbol(int ac, t_atom *av, int opt, int *skipp)
+{
+ int ndx;
+ for (ndx = 0; ndx < ac; ndx++, av++)
+ {
+ if (av->a_type == A_SYMBOL &&
+ (!opt || pddplink_isoption(av->a_w.w_symbol->s_name)))
+ {
+ *skipp = ++ndx;
+ return (av->a_w.w_symbol);
+ }
+ }
+ return (0);
+}
+
+static int pddplink_dooptext(char *dst, int maxsize, int ac, t_atom *av)
+{
+ int i, sz, sep, len;
+ char buf[32], *src;
+ for (i = 0, sz = 0, sep = 0; i < ac; i++, av++)
+ {
+ if (sep)
+ {
+ sz++;
+ if (sz >= maxsize)
+ break;
+ else if (dst)
+ {
+ *dst++ = ' ';
+ *dst = 0;
+ }
+ }
+ else sep = 1;
+ if (av->a_type == A_SYMBOL)
+ src = av->a_w.w_symbol->s_name;
+ else if (av->a_type == A_FLOAT)
+ {
+ src = buf;
+ sprintf(src, "%g", av->a_w.w_float);
+ }
+ else
+ {
+ sep = 0;
+ continue;
+ }
+ len = strlen(src);
+ sz += len;
+ if (sz >= maxsize)
+ break;
+ else if (dst)
+ {
+ strcpy(dst, src);
+ dst += len;
+ }
+ }
+ return (sz);
+}
+
+static char *pddplink_optext(int *sizep, int ac, t_atom *av)
+{
+ char *result;
+ int sz = pddplink_dooptext(0, MAXPDSTRING, ac, av);
+ *sizep = sz + (sz >= MAXPDSTRING ? 4 : 1);
+ result = getbytes(*sizep);
+ pddplink_dooptext(result, sz + 1, ac, av);
+ if (sz >= MAXPDSTRING)
+ {
+ sz = strlen(result);
+ strcpy(result + sz, "...");
+ }
+ return (result);
+}
+
#ifdef PDDPLINK_DEBUG
static void pddplink_debug(t_pddplink *x)
{
@@ -74,36 +285,77 @@ static void pddplink_debug(t_pddplink *x)
static void pddplink_free(t_pddplink *x)
{
+ if (x->x_vistext)
+ freebytes(x->x_vistext, x->x_vissize);
}
-static void *pddplink_new(t_symbol *s1, t_symbol *s2)
+static void *pddplink_new(t_symbol *s, int ac, t_atom *av)
{
- t_pddplink *x = (t_pddplink *)pd_new(pddplink_class);
- t_symbol *dirsym;
- x->x_glist = canvas_getcurrent();
- x->x_isboxed = (s2 == gensym("box"));
- x->x_dirsym = canvas_getdir(x->x_glist); /* FIXME */
- if (!s1 || s1 == &s_)
+ t_pddplink xgen, *x;
+ int skip;
+ xgen.x_isboxed = 0;
+ xgen.x_vistext = 0;
+ xgen.x_vissize = 0;
+ if (xgen.x_ulink = pddplink_nextsymbol(ac, av, 0, &skip))
{
- x->x_linktype = PDDPLINK_HTML;
- x->x_ulink = gensym("index.html");
+ t_symbol *opt;
+ ac -= skip;
+ av += skip;
+ while (opt = pddplink_nextsymbol(ac, av, 1, &skip))
+ {
+ ac -= skip;
+ av += skip;
+ if (opt == gensym("-box"))
+ xgen.x_isboxed = 1;
+ else if (opt == gensym("-text"))
+ {
+ t_symbol *nextsym = pddplink_nextsymbol(ac, av, 1, &skip);
+ int natoms = (nextsym ? skip - 1 : ac);
+ if (natoms)
+ xgen.x_vistext =
+ pddplink_optext(&xgen.x_vissize, natoms, av);
+ }
+ }
}
- else
+ x = (t_pddplink *)
+ pd_new(xgen.x_isboxed ? pddplinkbox_class : pddplink_class);
+ x->x_glist = canvas_getcurrent();
+ x->x_dirsym = canvas_getdir(x->x_glist); /* FIXME */
+
+ x->x_isboxed = xgen.x_isboxed;
+ x->x_vistext = xgen.x_vistext;
+ x->x_vissize = xgen.x_vissize;
+ x->x_vislength = (x->x_vistext ? strlen(x->x_vistext) : 0);
+ x->x_rtextactive = 0;
+ if (xgen.x_ulink)
{
- int len = strlen(s1->s_name);
- if (len > 3 && !strcmp(s1->s_name + len - 3, ".pd"))
+ int len = strlen(xgen.x_ulink->s_name);
+ if (len > 3 && !strcmp(xgen.x_ulink->s_name + len - 3, ".pd"))
x->x_linktype = PDDPLINK_PD;
else
x->x_linktype = PDDPLINK_HTML;
- x->x_ulink = s1;
+ x->x_ulink = xgen.x_ulink;
+ }
+ else
+ {
+ x->x_linktype = PDDPLINK_HTML;
+ x->x_ulink = gensym("index.html");
}
SETSYMBOL(&x->x_openargs[0], x->x_ulink);
SETSYMBOL(&x->x_openargs[1], x->x_dirsym);
x->x_ishit = 0;
if (x->x_isboxed)
- {
- inlet_new((t_object *)x, (t_pd *)x, 0, 0);
outlet_new((t_object *)x, &s_anything);
+ else
+ {
+ /* do we need to set ((t_text *)x)->te_type = T_TEXT; ? */
+ if (!x->x_vistext)
+ {
+ x->x_vislength = strlen(x->x_ulink->s_name);
+ x->x_vissize = x->x_vislength + 1;
+ x->x_vistext = getbytes(x->x_vissize);
+ strcpy(x->x_vistext, x->x_ulink->s_name);
+ }
}
if (x->x_linktype == PDDPLINK_HTML)
sys_vgui("after 0 {::pddp::srvUse %s}\n", x->x_dirsym->s_name);
@@ -115,22 +367,34 @@ void pddplink_setup(void)
t_symbol *dirsym;
post("this is pddplink %s, %s %s build...",
PDDP_VERSION, loud_ordinal(PDDP_BUILD), PDDP_RELEASE);
+
pddplink_class = class_new(gensym("pddplink"),
(t_newmethod)pddplink_new,
(t_method)pddplink_free,
sizeof(t_pddplink),
CLASS_NOINLET | CLASS_PATCHABLE,
- A_DEFSYM, A_DEFSYM, 0);
+ A_GIMME, 0);
class_addanything(pddplink_class, pddplink_anything);
- class_addmethod(pddplink_class, (t_method)pddplink_click,
+ class_setwidget(pddplink_class, &pddplink_widgetbehavior);
+
+ pddplinkbox_class = class_new(gensym("pddplink"), 0,
+ (t_method)pddplink_free,
+ sizeof(t_pddplink), 0, A_GIMME, 0);
+ class_addanything(pddplinkbox_class, pddplink_anything);
+ class_addmethod(pddplinkbox_class, (t_method)pddplink_click,
gensym("click"),
A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
+
#ifdef PDDPLINK_DEBUG
class_addmethod(pddplink_class, (t_method)pddplink_debug,
gensym("debug"), 0);
+ class_addmethod(pddplinkbox_class, (t_method)pddplink_debug,
+ gensym("debug"), 0);
#endif
+
dirsym = pddplink_class->c_externdir; /* FIXME */
- sys_vgui("namespace eval ::pddp {variable theDir [pwd]}; cd %s\n",
- dirsym->s_name);
- sys_gui("after 0 {source pddpboot.tcl}\n");
+ sys_vgui(
+ "if {[lsearch $auto_path \"%s\"] < 0} {lappend auto_path \"%s\"}\n",
+ dirsym->s_name, dirsym->s_name);
+ sys_gui("after 0 {package require pddp}\n");
}