diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | helplink-help.pd | 14 | ||||
-rw-r--r-- | helplink.c | 290 |
3 files changed, 305 insertions, 1 deletions
@@ -5,7 +5,7 @@ LIBRARY_NAME = pddp # add your .c source files to the SOURCES variable, help files will be # included automatically -SOURCES = pddplink.c +SOURCES = pddplink.c helplink.c # For objects that only build on certain platforms, add those to the SOURCES # line for the right platforms. diff --git a/helplink-help.pd b/helplink-help.pd new file mode 100644 index 0000000..675458f --- /dev/null +++ b/helplink-help.pd @@ -0,0 +1,14 @@ +#N canvas 314 87 424 397 12; +#X text 20 10 first entry; +#X text 50 50 three ways of linking to a; +#X text 50 170 three ways of linking to a; +#X obj 50 195 helplink http://puredata.info; +#X obj 50 230 helplink http://puredata.info -box; +#X text 50 290 three ways of linking to; +#X obj 260 290 helplink dsp-help.pd -text another local patch; +#X obj 50 315 helplink dsp-help.pd; +#X obj 50 350 helplink dsp-help.pd -box; +#X obj 270 170 helplink http://puredata.info -text remote URL; +#X obj 270 50 helplink README.txt -text local file; +#X obj 50 75 helplink README.txt; +#X obj 50 110 helplink README.txt -box; diff --git a/helplink.c b/helplink.c new file mode 100644 index 0000000..468fba5 --- /dev/null +++ b/helplink.c @@ -0,0 +1,290 @@ +/* Copyright (c) 2005 krzYszcz and others. + * 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" +#include "m_imp.h" /* FIXME need access to c_externdir... */ +#include "g_canvas.h" + +/* this isn't in any header, but its declared in s_path.c */ +void open_via_helppath(const char *name, const char *dir); + +typedef struct _helplink +{ + t_object x_ob; + t_glist *x_glist; + int x_isboxed; + int x_isgopvisible; + char *x_vistext; + int x_vissize; + int x_vislength; + int x_rtextactive; + t_symbol *x_ulink; + t_atom x_openargs[2]; + int x_linktype; + int x_ishit; +} t_helplink; + +static t_class *helplink_class; + +/* Code that might be merged back to g_text.c starts here: */ + +static void helplink_getrect(t_gobj *z, t_glist *glist, + int *xp1, int *yp1, int *xp2, int *yp2) +{ + t_helplink *x = (t_helplink *)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 helplink_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 helplink_select(t_gobj *z, t_glist *glist, int state) +{ + t_helplink *x = (t_helplink *)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 #0000dd -activefill #e70000\n", + glist, rtext_gettag(y), x->x_vistext); + } +} + +static void helplink_activate(t_gobj *z, t_glist *glist, int state) +{ + t_helplink *x = (t_helplink *)z; + t_rtext *y = glist_findrtext(glist, (t_text *)x); + rtext_activate(y, state); + x->x_rtextactive = state; +} + +static void helplink_vis(t_gobj *z, t_glist *glist, int vis) +{ + t_helplink *x = (t_helplink *)z; + t_rtext *y; + if (vis) + { + if ((glist->gl_havewindow || x->x_isgopvisible) + && (y = glist_findrtext(glist, (t_text *)x))) + { + rtext_draw(y); + sys_vgui(".x%lx.c itemconfigure %s -text {%s} -fill #0000dd -activefill #e70000\n", + glist_getcanvas(glist), rtext_gettag(y), x->x_vistext); + } + } + else + { + if ((glist->gl_havewindow || x->x_isgopvisible) + && (y = glist_findrtext(glist, (t_text *)x))) + rtext_erase(y); + } +} + +static int helplink_wbclick(t_gobj *z, t_glist *glist, int xpix, int ypix, + int shift, int alt, int dbl, int doit); + +static t_widgetbehavior helplink_widgetbehavior = +{ + helplink_getrect, + helplink_displace, + helplink_select, + helplink_activate, + 0, + helplink_vis, + helplink_wbclick, +}; + +/* Code that might be merged back to g_text.c ends here. */ + +/* FIXME need access to glob_pdobject... */ +static t_pd *helplink_pdtarget(t_helplink *x) +{ + t_pd *pdtarget = gensym("pd")->s_thing; + if (pdtarget && !strcmp(class_getname(*pdtarget), "pd")) + return (pdtarget); + else + return ((t_pd *)x); /* internal error */ +} + +static void helplink_anything(t_helplink *x, t_symbol *s, int ac, t_atom *av) +{ + if (x->x_ishit) + { + startpost("helplink: internal error (%s", (s ? s->s_name : "")); + postatom(ac, av); + post(")"); + } +} + +static void helplink_click(t_helplink *x, t_floatarg xpos, t_floatarg ypos, + t_floatarg shift, t_floatarg ctrl, t_floatarg alt) +{ + x->x_ishit = 1; +// open_via_helppath("intro.pd", canvas_getdir((t_canvas *)x)->s_name); + open_via_helppath(x->x_ulink->s_name, ""); + x->x_ishit = 0; +} + +static int helplink_wbclick(t_gobj *z, t_glist *glist, int xpix, int ypix, + int shift, int alt, int dbl, int doit) +{ + t_helplink *x = (t_helplink *)z; + if (glist->gl_havewindow || x->x_isgopvisible) + { + if (doit) + helplink_click(x, (t_floatarg)xpix, (t_floatarg)ypix, + (t_floatarg)shift, 0, (t_floatarg)alt); + return (1); + } + else return (0); +} + +static int helplink_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 *helplink_optext(int *sizep, int ac, t_atom *av) +{ + char *result; + int sz = helplink_dooptext(0, MAXPDSTRING, ac, av); + *sizep = sz + (sz >= MAXPDSTRING ? 4 : 1); + result = getbytes(*sizep); + helplink_dooptext(result, sz + 1, ac, av); + if (sz >= MAXPDSTRING) + { + sz = strlen(result); + strcpy(result + sz, "..."); + } + return (result); +} + +static void helplink_free(t_helplink *x) +{ + if (x->x_vistext) + freebytes(x->x_vistext, x->x_vissize); +} + +static void *helplink_new(t_symbol *s) +{ + t_helplink *x = (t_helplink *) pd_new(helplink_class); + + int skip; + x->x_isgopvisible = 0; + x->x_vistext = 0; + x->x_vissize = 0; + x->x_vislength = (x->x_vistext ? strlen(x->x_vistext) : 0); + x->x_rtextactive = 0; + x->x_glist = canvas_getcurrent(); + x->x_ulink = s; + if (! x->x_ulink) + x->x_ulink = gensym("helplink"); + SETSYMBOL(&x->x_openargs[0], x->x_ulink); + x->x_ishit = 0; + /* 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); + } + return (x); +} + +void helplink_setup(void) +{ + helplink_class = class_new(gensym("helplink"), + (t_newmethod)helplink_new, + (t_method)helplink_free, + sizeof(t_helplink), + CLASS_NOINLET | CLASS_PATCHABLE, + A_DEFSYMBOL, 0); + class_addanything(helplink_class, helplink_anything); + class_setwidget(helplink_class, &helplink_widgetbehavior); + +} |