aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--helplink-help.pd14
-rw-r--r--helplink.c290
3 files changed, 305 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 0992ac0..0080ddd 100644
--- a/Makefile
+++ b/Makefile
@@ -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);
+
+}