aboutsummaryrefslogtreecommitdiff
path: root/toxy/pluswidget.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxy/pluswidget.c')
-rw-r--r--toxy/pluswidget.c249
1 files changed, 249 insertions, 0 deletions
diff --git a/toxy/pluswidget.c b/toxy/pluswidget.c
new file mode 100644
index 0000000..050b2a1
--- /dev/null
+++ b/toxy/pluswidget.c
@@ -0,0 +1,249 @@
+/* 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 a custom object box. It might be replaced with
+ a new core object type, T_CUSTOM (te_type bitfield would have to be
+ extended then). */
+
+#include <stdio.h>
+#include <string.h>
+#include "m_pd.h"
+#include "g_canvas.h"
+#include "common/loud.h"
+#include "toxy/plusbob.h"
+#include "plustot.h"
+
+#ifdef KRZYSZCZ
+//#define PLUSWIDGET_DEBUG
+#endif
+
+struct _pluswidget
+{
+ char *pw_vistext; /* binbuf_gettext()-style (no null termination) */
+ int pw_vissize;
+ int pw_rtextactive;
+ int pw_ishit;
+};
+
+/* Code that might be merged back to g_text.c starts here: */
+
+static void pluswidget_getrect(t_gobj *z, t_glist *glist,
+ int *xp1, int *yp1, int *xp2, int *yp2)
+{
+ t_pluswidget *pw = ((t_plusobject *)z)->po_widget;
+ int width, height;
+ float x1, y1, x2, y2;
+ if (glist->gl_editor && glist->gl_editor->e_rtext)
+ {
+ if (pw->pw_rtextactive)
+ {
+ t_rtext *y = glist_findrtext(glist, (t_text *)z);
+ width = rtext_width(y);
+ height = rtext_height(y);
+ }
+ else
+ {
+ int font = glist_getfont(glist);
+ width = pw->pw_vissize * sys_fontwidth(font) + 2;
+ height = sys_fontheight(font) + 4; /* 2-pixel top/bottom margins */
+ }
+ }
+ else width = height = 10;
+ x1 = text_xpix((t_text *)z, glist);
+ y1 = text_ypix((t_text *)z, glist);
+ x2 = x1 + width;
+ y2 = y1 + height;
+ y1 += 1;
+ *xp1 = x1;
+ *yp1 = y1;
+ *xp2 = x2;
+ *yp2 = y2;
+}
+
+static void pluswidget_drawiofor(t_glist *glist, t_plusobject *po,
+ int firsttime,
+ char *tag, int x1, int y1, int x2, int y2)
+{
+ int n, nplus, i, width = x2 - x1;
+ for (n = po->po_noutlets, nplus = (n == 1 ? 1 : n-1), i = 0; i < n; i++)
+ {
+ int onset = x1 + (width - IOWIDTH) * i / nplus;
+ if (firsttime)
+ sys_vgui(".x%lx.c create rectangle %d %d %d %d -tags %so%d\
+ -outline brown -fill lightgrey\n",
+ glist_getcanvas(glist),
+ onset, y2 - 3,
+ onset + IOWIDTH, y2 + 2,
+ tag, i);
+ else
+ sys_vgui(".x%lx.c coords %so%d %d %d %d %d\n",
+ glist_getcanvas(glist), tag, i,
+ onset, y2 - 3,
+ onset + IOWIDTH, y2 + 2);
+ }
+ for (n = po->po_ninlets, nplus = (n == 1 ? 1 : n-1), i = 0; i < n; i++)
+ {
+ int onset = x1 + (width - IOWIDTH) * i / nplus;
+ if (firsttime)
+ sys_vgui(".x%lx.c create rectangle %d %d %d %d -tags %si%d\
+ -outline brown -fill lightgrey\n",
+ glist_getcanvas(glist),
+ onset, y1 - 3,
+ onset + IOWIDTH, y1 + 2,
+ tag, i);
+ else
+ sys_vgui(".x%lx.c coords %si%d %d %d %d %d\n",
+ glist_getcanvas(glist), tag, i,
+ onset, y1 - 3,
+ onset + IOWIDTH, y1 + 2);
+ }
+}
+
+static void pluswidget_drawborder(t_text *t, t_glist *glist,
+ char *tag, int firsttime)
+{
+ int x1, y1, x2, y2;
+ pluswidget_getrect(&t->te_g, glist, &x1, &y1, &x2, &y2);
+ if (firsttime)
+ sys_vgui(".x%lx.c create line\
+ %d %d %d %d %d %d %d %d %d %d -width 2 -fill brown -tags %sR\n",
+ glist_getcanvas(glist),
+ x1, y1, x2, y1, x2, y2, x1, y2, x1, y1, tag);
+ else
+ sys_vgui(".x%lx.c coords %sR\
+ %d %d %d %d %d %d %d %d %d %d\n",
+ glist_getcanvas(glist), tag,
+ x1, y1, x2, y1, x2, y2, x1, y2, x1, y1);
+ pluswidget_drawiofor(glist, (t_plusobject *)t, firsttime,
+ tag, x1, y1, x2, y2);
+}
+
+static void pluswidget_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);
+ pluswidget_drawborder(t, glist, rtext_gettag(y), 0);
+ canvas_fixlinesfor(glist_getcanvas(glist), t);
+ }
+}
+
+static void pluswidget_select(t_gobj *z, t_glist *glist, int state)
+{
+ t_pluswidget *pw = ((t_plusobject *)z)->po_widget;
+ t_rtext *y = glist_findrtext(glist, (t_text *)z);
+ 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 brown\n",
+ glist, rtext_gettag(y), pw->pw_vissize, pw->pw_vistext);
+ }
+}
+
+static void pluswidget_activate(t_gobj *z, t_glist *glist, int state)
+{
+ t_pluswidget *pw = ((t_plusobject *)z)->po_widget;
+ t_rtext *y = glist_findrtext(glist, (t_text *)z);
+ rtext_activate(y, state);
+ pw->pw_rtextactive = state;
+ pluswidget_drawborder((t_text *)z, glist, rtext_gettag(y), 0);
+}
+
+static void pluswidget_delete(t_gobj *z, t_glist *glist)
+{
+ canvas_deletelinesfor(glist, (t_text *)z);
+}
+
+static void pluswidget_vis(t_gobj *z, t_glist *glist, int vis)
+{
+ t_pluswidget *pw = ((t_plusobject *)z)->po_widget;
+ if (vis)
+ {
+ if (glist->gl_havewindow)
+ {
+ t_rtext *y = glist_findrtext(glist, (t_text *)z);
+ pluswidget_drawborder((t_text *)z, glist, rtext_gettag(y), 1);
+ rtext_draw(y);
+ sys_vgui(".x%lx.c itemconfigure %s -text {%.*s} -fill brown\n",
+ glist, rtext_gettag(y), pw->pw_vissize, pw->pw_vistext);
+ }
+ }
+ else
+ {
+ if (glist->gl_havewindow)
+ {
+ t_rtext *y = glist_findrtext(glist, (t_text *)z);
+ text_eraseborder((t_text *)z, glist, rtext_gettag(y));
+ rtext_erase(y);
+ }
+ }
+}
+
+static int pluswidget_click(t_gobj *z, t_glist *glist, int xpix, int ypix,
+ int shift, int alt, int dbl, int doit)
+{
+ if (doit)
+ pd_bang((t_pd *)z);
+ return (1);
+}
+
+static t_widgetbehavior pluswidget_widgetbehavior =
+{
+ pluswidget_getrect,
+ pluswidget_displace,
+ pluswidget_select,
+ pluswidget_activate,
+ pluswidget_delete,
+ pluswidget_vis,
+ pluswidget_click,
+};
+
+/* Code that might be merged back to g_text.c ends here. */
+
+void plusobject_widgetfree(t_plusobject *po)
+{
+ t_pluswidget *pw = po->po_widget;
+ if (pw)
+ {
+ if (pw->pw_vistext)
+ freebytes(pw->pw_vistext, pw->pw_vissize);
+ freebytes(pw, sizeof(*pw));
+ }
+}
+
+void plusobject_widgetcreate(t_plusobject *po, t_symbol *s, int ac, t_atom *av)
+{
+ t_pluswidget *pw = getbytes(sizeof(*pw));
+ t_binbuf *inbb = binbuf_new();
+ if (!s || s == &s_)
+ s = plusps_tot;
+ po->po_widget = pw;
+ if ((s != totps_plustot && s != plusps_tot) || ac == 0)
+ {
+ t_atom at;
+ if (s == totps_plustot)
+ s = plusps_tot;
+ SETSYMBOL (&at, s);
+ binbuf_add(inbb, 1, &at);
+ }
+ if (ac > 0)
+ binbuf_add(inbb, ac, av);
+ binbuf_gettext(inbb, &pw->pw_vistext, &pw->pw_vissize);
+ binbuf_free(inbb);
+ pw->pw_rtextactive = 0;
+ pw->pw_ishit = 0;
+}
+
+void plusclass_widgetsetup(t_class *c)
+{
+ class_setwidget(c, &pluswidget_widgetbehavior);
+}