summaryrefslogtreecommitdiff
path: root/apps/plugins/pdbox/PDa/src/g_scalar.c
diff options
context:
space:
mode:
authorPeter D'Hoye <peter.dhoye@gmail.com>2009-05-22 21:58:48 +0000
committerPeter D'Hoye <peter.dhoye@gmail.com>2009-05-22 21:58:48 +0000
commit513389b4c1bc8afe4b2dc9947c534bfeb105e3da (patch)
tree10e673b35651ac567fed2eda0c679c7ade64cbc6 /apps/plugins/pdbox/PDa/src/g_scalar.c
parent95fa7f6a2ef466444fbe3fe87efc6d5db6b77b36 (diff)
downloadrockbox-513389b4c1bc8afe4b2dc9947c534bfeb105e3da.tar.gz
rockbox-513389b4c1bc8afe4b2dc9947c534bfeb105e3da.zip
Add FS #10214. Initial commit of the original PDa code for the GSoC Pure Data plugin project of Wincent Balin. Stripped some non-sourcefiles and added a rockbox readme that needs a bit more info from Wincent. Is added to CATEGORIES and viewers, but not yet to SUBDIRS (ie doesn't build yet)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21044 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/pdbox/PDa/src/g_scalar.c')
-rw-r--r--apps/plugins/pdbox/PDa/src/g_scalar.c802
1 files changed, 802 insertions, 0 deletions
diff --git a/apps/plugins/pdbox/PDa/src/g_scalar.c b/apps/plugins/pdbox/PDa/src/g_scalar.c
new file mode 100644
index 0000000000..b3c6d824fc
--- /dev/null
+++ b/apps/plugins/pdbox/PDa/src/g_scalar.c
@@ -0,0 +1,802 @@
1/* Copyright (c) 1997-1999 Miller Puckette.
2* For information on usage and redistribution, and for a DISCLAIMER OF ALL
3* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
4
5/* This file defines the "scalar" object, which is not a text object, just a
6"gobj". Scalars have templates which describe their structures, which
7can contain numbers, sublists, and arrays.
8
9Also, the "tscalar" object, an ordinary text object that owns a single "scalar"
10and draws it on the parent. This is intended as a way that abstractions can
11control their appearances by adding stuff to draw.
12*/
13
14/* IOhannes :
15 * changed the canvas_restore, so that it might accept $args as well (like "pd $0_test")
16 * so you can make multiple & distinguishable templates
17 * 1511:forum::für::umläute:2001
18 * changes marked with IOhannes
19 * added Krzysztof Czajas fix to avoid crashing...
20 */
21
22#include <stdlib.h>
23#include <string.h>
24#include <stdio.h> /* for read/write to files */
25#include "m_pd.h"
26#include "g_canvas.h"
27
28t_class *scalar_class;
29
30void word_init(t_word *wp, t_template *template, t_gpointer *gp)
31{
32 int i, nitems = template->t_n;
33 t_dataslot *datatypes = template->t_vec;
34 for (i = 0; i < nitems; i++, datatypes++, wp++)
35 {
36 int type = datatypes->ds_type;
37 if (type == DT_FLOAT)
38 wp->w_float = 0;
39 else if (type == DT_SYMBOL)
40 wp->w_symbol = &s_symbol;
41 else if (type == DT_ARRAY)
42 {
43 wp->w_array = array_new(datatypes->ds_arraytemplate, gp);
44 }
45 else if (type == DT_LIST)
46 {
47 /* LATER test this and get it to work */
48 wp->w_list = canvas_new(0, 0, 0, 0);
49 }
50 }
51}
52
53void word_restore(t_word *wp, t_template *template,
54 int argc, t_atom *argv)
55{
56 int i, nitems = template->t_n;
57 t_dataslot *datatypes = template->t_vec;
58 for (i = 0; i < nitems; i++, datatypes++, wp++)
59 {
60 int type = datatypes->ds_type;
61 if (type == DT_FLOAT)
62 {
63 float f;
64 if (argc)
65 {
66 f = atom_getfloat(argv);
67 argv++, argc--;
68 }
69 else f = 0;
70 wp->w_float = f;
71 }
72 else if (type == DT_SYMBOL)
73 {
74 t_symbol *s;
75 if (argc)
76 {
77 s = atom_getsymbol(argv);
78 argv++, argc--;
79 }
80 else s = &s_;
81 wp->w_symbol = s;
82 }
83 }
84 if (argc)
85 post("warning: word_restore: extra arguments");
86}
87
88void word_free(t_word *wp, t_template *template)
89{
90 int i;
91 t_dataslot *dt;
92 for (dt = template->t_vec, i = 0; i < template->t_n; i++, dt++)
93 {
94 if (dt->ds_type == DT_ARRAY)
95 array_free(wp[i].w_array);
96 else if (dt->ds_type == DT_LIST)
97 canvas_free(wp[i].w_list);
98 }
99}
100
101 /* make a new scalar and add to the glist. We create a "gp" here which
102 will be used for array items to point back here. This gp doesn't do
103 reference counting or "validation" updates though; the parent won't go away
104 without the contained arrays going away too. The "gp" is copied out
105 by value in the word_init() routine so we can throw our copy away. */
106
107t_scalar *scalar_new(t_glist *owner, t_symbol *templatesym)
108{
109 t_scalar *x;
110 t_template *template;
111 t_gpointer gp;
112 gpointer_init(&gp);
113 template = template_findbyname(templatesym);
114 if (!template)
115 {
116 error("scalar: couldn't find template %s", templatesym->s_name);
117 return (0);
118 }
119 x = (t_scalar *)getbytes(sizeof(t_scalar) +
120 (template->t_n - 1) * sizeof(*x->sc_vec));
121 x->sc_gobj.g_pd = scalar_class;
122 x->sc_template = templatesym;
123 gpointer_setglist(&gp, owner, x);
124 word_init(x->sc_vec, template, &gp);
125 return (x);
126}
127
128 /* Pd method to create a new scalar, add it to a glist, and initialize
129 it from the message arguments. */
130
131int glist_readscalar(t_glist *x, int natoms, t_atom *vec,
132 int *p_nextmsg, int selectit);
133
134void glist_scalar(t_glist *glist,
135 t_symbol *classname, t_int argc, t_atom *argv)
136{
137 t_symbol *templatesym =
138 canvas_makebindsym(atom_getsymbolarg(0, argc, argv));
139 t_binbuf *b;
140 int natoms, nextmsg = 0;
141 t_atom *vec;
142 if (!template_findbyname(templatesym))
143 {
144 pd_error(glist, "%s: no such template",
145 atom_getsymbolarg(0, argc, argv)->s_name);
146 return;
147 }
148
149 b = binbuf_new();
150 binbuf_restore(b, argc, argv);
151 natoms = binbuf_getnatom(b);
152 vec = binbuf_getvec(b);
153
154 glist_readscalar(glist, natoms, vec, &nextmsg, 0);
155 binbuf_free(b);
156}
157
158/* -------------------- widget behavior for scalar ------------ */
159void scalar_getbasexy(t_scalar *x, float *basex, float *basey)
160{
161 t_template *template = template_findbyname(x->sc_template);
162 *basex = template_getfloat(template, gensym("x"), x->sc_vec, 0);
163 *basey = template_getfloat(template, gensym("y"), x->sc_vec, 0);
164}
165
166static void scalar_getrect(t_gobj *z, t_glist *owner,
167 int *xp1, int *yp1, int *xp2, int *yp2)
168{
169 t_scalar *x = (t_scalar *)z;
170 int hit = 0;
171 t_template *template = template_findbyname(x->sc_template);
172 t_canvas *templatecanvas = template_findcanvas(template);
173 int x1 = 0x7fffffff, x2 = -0x7fffffff, y1 = 0x7fffffff, y2 = -0x7fffffff;
174 t_gobj *y;
175 float basex, basey;
176 scalar_getbasexy(x, &basex, &basey);
177 /* if someone deleted the template canvas, we're just a point */
178 if (!templatecanvas)
179 {
180 x1 = x2 = glist_xtopixels(owner, basex);
181 y1 = y2 = glist_ytopixels(owner, basey);
182 }
183 else
184 {
185 int hit = 0;
186 x1 = y1 = 0x7fffffff;
187 x2 = y2 = -0x7fffffff;
188 for (y = templatecanvas->gl_list; y; y = y->g_next)
189 {
190 t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd);
191 int nx1, ny1, nx2, ny2;
192 if (!wb) continue;
193 (*wb->w_parentgetrectfn)(y, owner,
194 x->sc_vec, template, basex, basey,
195 &nx1, &ny1, &nx2, &ny2);
196 if (hit)
197 {
198 if (nx1 < x1) x1 = nx1;
199 if (ny1 < y1) y1 = ny1;
200 if (nx2 > x2) x2 = nx2;
201 if (ny2 > y2) y2 = ny2;
202 }
203 else x1 = nx1, y1 = ny1, x2 = nx2, y2 = ny2, hit = 1;
204 }
205 if (!hit) x1 = y1 = x2 = y2 = 0;
206 }
207 /* post("scalar x1 %d y1 %d x2 %d y2 %d", x1, y1, x2, y2); */
208 *xp1 = x1;
209 *yp1 = y1;
210 *xp2 = x2;
211 *yp2 = y2;
212}
213
214static void scalar_select(t_gobj *z, t_glist *owner, int state)
215{
216 t_scalar *x = (t_scalar *)z;
217 /* post("scalar_select %d", state); */
218 /* later */
219 if (state)
220 {
221 int x1, y1, x2, y2;
222 scalar_getrect(z, owner, &x1, &y1, &x2, &y2);
223 x1--; x2++; y1--; y2++;
224 sys_vgui(".x%x.c create line %d %d %d %d %d %d %d %d %d %d \
225 -width 0 -fill blue -tags select%x\n",
226 glist_getcanvas(owner), x1, y1, x1, y2, x2, y2, x2, y1, x1, y1,
227 x);
228 }
229 else sys_vgui(".x%x.c delete select%x\n", glist_getcanvas(owner), x);
230}
231
232static void scalar_displace(t_gobj *z, t_glist *glist, int dx, int dy)
233{
234 t_scalar *x = (t_scalar *)z;
235 t_symbol *templatesym = x->sc_template;
236 t_template *template = template_findbyname(templatesym);
237 t_symbol *zz;
238 int xonset, yonset, xtype, ytype, gotx, goty;
239 if (!template)
240 {
241 error("scalar: couldn't find template %s", templatesym->s_name);
242 return;
243 }
244 gotx = template_find_field(template, gensym("x"), &xonset, &xtype, &zz);
245 if (gotx && (xtype != DT_FLOAT))
246 gotx = 0;
247 goty = template_find_field(template, gensym("y"), &yonset, &ytype, &zz);
248 if (goty && (ytype != DT_FLOAT))
249 goty = 0;
250 if (gotx)
251 *(t_float *)(((char *)(x->sc_vec)) + xonset) +=
252 dx * (glist_pixelstox(glist, 1) - glist_pixelstox(glist, 0));
253 if (goty)
254 *(t_float *)(((char *)(x->sc_vec)) + yonset) +=
255 dy * (glist_pixelstoy(glist, 1) - glist_pixelstoy(glist, 0));
256 glist_redrawitem(glist, z);
257 if (glist_isselected(glist, z))
258 {
259 scalar_select(z, glist, 0);
260 scalar_select(z, glist, 1);
261 }
262}
263
264static void scalar_activate(t_gobj *z, t_glist *owner, int state)
265{
266 /* post("scalar_activate %d", state); */
267 /* later */
268}
269
270static void scalar_delete(t_gobj *z, t_glist *glist)
271{
272 /* nothing to do */
273}
274
275static void scalar_vis(t_gobj *z, t_glist *owner, int vis)
276{
277 t_scalar *x = (t_scalar *)z;
278 t_template *template = template_findbyname(x->sc_template);
279 t_canvas *templatecanvas = template_findcanvas(template);
280 t_gobj *y;
281 float basex, basey;
282 scalar_getbasexy(x, &basex, &basey);
283 /* if we don't know how to draw it, make a small rectangle */
284 if (!templatecanvas)
285 {
286 if (vis)
287 {
288 int x1 = glist_xtopixels(owner, basex);
289 int y1 = glist_ytopixels(owner, basey);
290 sys_vgui(".x%x.c create rectangle %d %d %d %d -tags scalar%x\n",
291 glist_getcanvas(owner), x1-1, y1-1, x1+1, y1+1, x);
292 }
293 else sys_vgui(".x%x.c delete scalar%x\n", glist_getcanvas(owner), x);
294 return;
295 }
296
297 for (y = templatecanvas->gl_list; y; y = y->g_next)
298 {
299 t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd);
300 if (!wb) continue;
301 (*wb->w_parentvisfn)(y, owner, x->sc_vec, template, basex, basey, vis);
302 }
303}
304
305static int scalar_click(t_gobj *z, struct _glist *owner,
306 int xpix, int ypix, int shift, int alt, int dbl, int doit)
307{
308 t_scalar *x = (t_scalar *)z;
309 int hit = 0;
310 t_template *template = template_findbyname(x->sc_template);
311 t_canvas *templatecanvas = template_findcanvas(template);
312 t_gobj *y;
313 float basex, basey;
314 scalar_getbasexy(x, &basex, &basey);
315 for (y = templatecanvas->gl_list; y; y = y->g_next)
316 {
317 t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd);
318 if (!wb) continue;
319 if (hit = (*wb->w_parentclickfn)(y, owner,
320 x, template, basex, basey,
321 xpix, ypix, shift, alt, dbl, doit))
322 return (hit);
323 }
324 return (0);
325}
326
327void canvas_writescalar(t_symbol *templatesym, t_word *w, t_binbuf *b,
328 int amarrayelement);
329
330static void scalar_save(t_gobj *z, t_binbuf *b)
331{
332 t_scalar *x = (t_scalar *)z;
333 t_binbuf *b2 = binbuf_new();
334 t_atom a, *argv;
335 int i, argc;
336 canvas_writescalar(x->sc_template, x->sc_vec, b2, 0);
337 binbuf_addv(b, "ss", &s__X, gensym("scalar"));
338 binbuf_addbinbuf(b, b2);
339 binbuf_addsemi(b);
340 binbuf_free(b2);
341}
342
343static void scalar_properties(t_gobj *z, struct _glist *owner)
344{
345 t_scalar *x = (t_scalar *)z;
346 char *buf, buf2[80];
347 int bufsize;
348 t_binbuf *b;
349 glist_noselect(owner);
350 glist_select(owner, z);
351 b = glist_writetobinbuf(owner, 0);
352 binbuf_gettext(b, &buf, &bufsize);
353 binbuf_free(b);
354 buf = t_resizebytes(buf, bufsize, bufsize+1);
355 buf[bufsize] = 0;
356 sprintf(buf2, "pdtk_data_dialog %%s {");
357 gfxstub_new((t_pd *)owner, x, buf2);
358 sys_gui(buf);
359 sys_gui("}\n");
360 t_freebytes(buf, bufsize+1);
361}
362
363static t_widgetbehavior scalar_widgetbehavior =
364{
365 scalar_getrect,
366 scalar_displace,
367 scalar_select,
368 scalar_activate,
369 scalar_delete,
370 scalar_vis,
371 scalar_click,
372};
373
374static void scalar_free(t_scalar *x)
375{
376 int i;
377 t_dataslot *datatypes, *dt;
378 t_symbol *templatesym = x->sc_template;
379 t_template *template = template_findbyname(templatesym);
380 if (!template)
381 {
382 error("scalar: couldn't find template %s", templatesym->s_name);
383 return;
384 }
385 word_free(x->sc_vec, template);
386 gfxstub_deleteforkey(x);
387 /* the "size" field in the class is zero, so Pd doesn't try to free
388 us automatically (see pd_free()) */
389 freebytes(x, sizeof(t_scalar) + (template->t_n - 1) * sizeof(*x->sc_vec));
390}
391
392/* ----------------- setup function ------------------- */
393
394void g_scalar_setup(void)
395{
396 scalar_class = class_new(gensym("scalar"), 0, (t_method)scalar_free, 0,
397 CLASS_GOBJ, 0);
398 class_setwidget(scalar_class, &scalar_widgetbehavior);
399 class_setsavefn(scalar_class, scalar_save);
400 class_setpropertiesfn(scalar_class, scalar_properties);
401}
402/* Copyright (c) 1997-1999 Miller Puckette.
403* For information on usage and redistribution, and for a DISCLAIMER OF ALL
404* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
405
406/* This file defines the "scalar" object, which is not a text object, just a
407"gobj". Scalars have templates which describe their structures, which
408can contain numbers, sublists, and arrays.
409
410Also, the "tscalar" object, an ordinary text object that owns a single "scalar"
411and draws it on the parent. This is intended as a way that abstractions can
412control their appearances by adding stuff to draw.
413*/
414
415/* IOhannes :
416 * changed the canvas_restore, so that it might accept $args as well (like "pd $0_test")
417 * so you can make multiple & distinguishable templates
418 * 1511:forum::für::umläute:2001
419 * changes marked with IOhannes
420 * added Krzysztof Czajas fix to avoid crashing...
421 */
422
423#include <stdlib.h>
424#include <string.h>
425#include <stdio.h> /* for read/write to files */
426#include "m_pd.h"
427#include "g_canvas.h"
428
429t_class *scalar_class;
430
431void word_init(t_word *wp, t_template *template, t_gpointer *gp)
432{
433 int i, nitems = template->t_n;
434 t_dataslot *datatypes = template->t_vec;
435 for (i = 0; i < nitems; i++, datatypes++, wp++)
436 {
437 int type = datatypes->ds_type;
438 if (type == DT_FLOAT)
439 wp->w_float = 0;
440 else if (type == DT_SYMBOL)
441 wp->w_symbol = &s_symbol;
442 else if (type == DT_ARRAY)
443 {
444 wp->w_array = array_new(datatypes->ds_arraytemplate, gp);
445 }
446 else if (type == DT_LIST)
447 {
448 /* LATER test this and get it to work */
449 wp->w_list = canvas_new(0, 0, 0, 0);
450 }
451 }
452}
453
454void word_restore(t_word *wp, t_template *template,
455 int argc, t_atom *argv)
456{
457 int i, nitems = template->t_n;
458 t_dataslot *datatypes = template->t_vec;
459 for (i = 0; i < nitems; i++, datatypes++, wp++)
460 {
461 int type = datatypes->ds_type;
462 if (type == DT_FLOAT)
463 {
464 float f;
465 if (argc)
466 {
467 f = atom_getfloat(argv);
468 argv++, argc--;
469 }
470 else f = 0;
471 wp->w_float = f;
472 }
473 else if (type == DT_SYMBOL)
474 {
475 t_symbol *s;
476 if (argc)
477 {
478 s = atom_getsymbol(argv);
479 argv++, argc--;
480 }
481 else s = &s_;
482 wp->w_symbol = s;
483 }
484 }
485 if (argc)
486 post("warning: word_restore: extra arguments");
487}
488
489void word_free(t_word *wp, t_template *template)
490{
491 int i;
492 t_dataslot *dt;
493 for (dt = template->t_vec, i = 0; i < template->t_n; i++, dt++)
494 {
495 if (dt->ds_type == DT_ARRAY)
496 array_free(wp[i].w_array);
497 else if (dt->ds_type == DT_LIST)
498 canvas_free(wp[i].w_list);
499 }
500}
501
502 /* make a new scalar and add to the glist. We create a "gp" here which
503 will be used for array items to point back here. This gp doesn't do
504 reference counting or "validation" updates though; the parent won't go away
505 without the contained arrays going away too. The "gp" is copied out
506 by value in the word_init() routine so we can throw our copy away. */
507
508t_scalar *scalar_new(t_glist *owner, t_symbol *templatesym)
509{
510 t_scalar *x;
511 t_template *template;
512 t_gpointer gp;
513 gpointer_init(&gp);
514 template = template_findbyname(templatesym);
515 if (!template)
516 {
517 error("scalar: couldn't find template %s", templatesym->s_name);
518 return (0);
519 }
520 x = (t_scalar *)getbytes(sizeof(t_scalar) +
521 (template->t_n - 1) * sizeof(*x->sc_vec));
522 x->sc_gobj.g_pd = scalar_class;
523 x->sc_template = templatesym;
524 gpointer_setglist(&gp, owner, x);
525 word_init(x->sc_vec, template, &gp);
526 return (x);
527}
528
529 /* Pd method to create a new scalar, add it to a glist, and initialize
530 it from the message arguments. */
531
532int glist_readscalar(t_glist *x, int natoms, t_atom *vec,
533 int *p_nextmsg, int selectit);
534
535void glist_scalar(t_glist *glist,
536 t_symbol *classname, t_int argc, t_atom *argv)
537{
538 t_symbol *templatesym =
539 canvas_makebindsym(atom_getsymbolarg(0, argc, argv));
540 t_binbuf *b;
541 int natoms, nextmsg = 0;
542 t_atom *vec;
543 if (!template_findbyname(templatesym))
544 {
545 pd_error(glist, "%s: no such template",
546 atom_getsymbolarg(0, argc, argv)->s_name);
547 return;
548 }
549
550 b = binbuf_new();
551 binbuf_restore(b, argc, argv);
552 natoms = binbuf_getnatom(b);
553 vec = binbuf_getvec(b);
554
555 glist_readscalar(glist, natoms, vec, &nextmsg, 0);
556 binbuf_free(b);
557}
558
559/* -------------------- widget behavior for scalar ------------ */
560void scalar_getbasexy(t_scalar *x, float *basex, float *basey)
561{
562 t_template *template = template_findbyname(x->sc_template);
563 *basex = template_getfloat(template, gensym("x"), x->sc_vec, 0);
564 *basey = template_getfloat(template, gensym("y"), x->sc_vec, 0);
565}
566
567static void scalar_getrect(t_gobj *z, t_glist *owner,
568 int *xp1, int *yp1, int *xp2, int *yp2)
569{
570 t_scalar *x = (t_scalar *)z;
571 int hit = 0;
572 t_template *template = template_findbyname(x->sc_template);
573 t_canvas *templatecanvas = template_findcanvas(template);
574 int x1 = 0x7fffffff, x2 = -0x7fffffff, y1 = 0x7fffffff, y2 = -0x7fffffff;
575 t_gobj *y;
576 float basex, basey;
577 scalar_getbasexy(x, &basex, &basey);
578 /* if someone deleted the template canvas, we're just a point */
579 if (!templatecanvas)
580 {
581 x1 = x2 = glist_xtopixels(owner, basex);
582 y1 = y2 = glist_ytopixels(owner, basey);
583 }
584 else
585 {
586 int hit = 0;
587 x1 = y1 = 0x7fffffff;
588 x2 = y2 = -0x7fffffff;
589 for (y = templatecanvas->gl_list; y; y = y->g_next)
590 {
591 t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd);
592 int nx1, ny1, nx2, ny2;
593 if (!wb) continue;
594 (*wb->w_parentgetrectfn)(y, owner,
595 x->sc_vec, template, basex, basey,
596 &nx1, &ny1, &nx2, &ny2);
597 if (hit)
598 {
599 if (nx1 < x1) x1 = nx1;
600 if (ny1 < y1) y1 = ny1;
601 if (nx2 > x2) x2 = nx2;
602 if (ny2 > y2) y2 = ny2;
603 }
604 else x1 = nx1, y1 = ny1, x2 = nx2, y2 = ny2, hit = 1;
605 }
606 if (!hit) x1 = y1 = x2 = y2 = 0;
607 }
608 /* post("scalar x1 %d y1 %d x2 %d y2 %d", x1, y1, x2, y2); */
609 *xp1 = x1;
610 *yp1 = y1;
611 *xp2 = x2;
612 *yp2 = y2;
613}
614
615static void scalar_select(t_gobj *z, t_glist *owner, int state)
616{
617 t_scalar *x = (t_scalar *)z;
618 /* post("scalar_select %d", state); */
619 /* later */
620 if (state)
621 {
622 int x1, y1, x2, y2;
623 scalar_getrect(z, owner, &x1, &y1, &x2, &y2);
624 x1--; x2++; y1--; y2++;
625 sys_vgui(".x%x.c create line %d %d %d %d %d %d %d %d %d %d \
626 -width 0 -fill blue -tags select%x\n",
627 glist_getcanvas(owner), x1, y1, x1, y2, x2, y2, x2, y1, x1, y1,
628 x);
629 }
630 else sys_vgui(".x%x.c delete select%x\n", glist_getcanvas(owner), x);
631}
632
633static void scalar_displace(t_gobj *z, t_glist *glist, int dx, int dy)
634{
635 t_scalar *x = (t_scalar *)z;
636 t_symbol *templatesym = x->sc_template;
637 t_template *template = template_findbyname(templatesym);
638 t_symbol *zz;
639 int xonset, yonset, xtype, ytype, gotx, goty;
640 if (!template)
641 {
642 error("scalar: couldn't find template %s", templatesym->s_name);
643 return;
644 }
645 gotx = template_find_field(template, gensym("x"), &xonset, &xtype, &zz);
646 if (gotx && (xtype != DT_FLOAT))
647 gotx = 0;
648 goty = template_find_field(template, gensym("y"), &yonset, &ytype, &zz);
649 if (goty && (ytype != DT_FLOAT))
650 goty = 0;
651 if (gotx)
652 *(t_float *)(((char *)(x->sc_vec)) + xonset) +=
653 dx * (glist_pixelstox(glist, 1) - glist_pixelstox(glist, 0));
654 if (goty)
655 *(t_float *)(((char *)(x->sc_vec)) + yonset) +=
656 dy * (glist_pixelstoy(glist, 1) - glist_pixelstoy(glist, 0));
657 glist_redrawitem(glist, z);
658 if (glist_isselected(glist, z))
659 {
660 scalar_select(z, glist, 0);
661 scalar_select(z, glist, 1);
662 }
663}
664
665static void scalar_activate(t_gobj *z, t_glist *owner, int state)
666{
667 /* post("scalar_activate %d", state); */
668 /* later */
669}
670
671static void scalar_delete(t_gobj *z, t_glist *glist)
672{
673 /* nothing to do */
674}
675
676static void scalar_vis(t_gobj *z, t_glist *owner, int vis)
677{
678 t_scalar *x = (t_scalar *)z;
679 t_template *template = template_findbyname(x->sc_template);
680 t_canvas *templatecanvas = template_findcanvas(template);
681 t_gobj *y;
682 float basex, basey;
683 scalar_getbasexy(x, &basex, &basey);
684 /* if we don't know how to draw it, make a small rectangle */
685 if (!templatecanvas)
686 {
687 if (vis)
688 {
689 int x1 = glist_xtopixels(owner, basex);
690 int y1 = glist_ytopixels(owner, basey);
691 sys_vgui(".x%x.c create rectangle %d %d %d %d -tags scalar%x\n",
692 glist_getcanvas(owner), x1-1, y1-1, x1+1, y1+1, x);
693 }
694 else sys_vgui(".x%x.c delete scalar%x\n", glist_getcanvas(owner), x);
695 return;
696 }
697
698 for (y = templatecanvas->gl_list; y; y = y->g_next)
699 {
700 t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd);
701 if (!wb) continue;
702 (*wb->w_parentvisfn)(y, owner, x->sc_vec, template, basex, basey, vis);
703 }
704}
705
706static int scalar_click(t_gobj *z, struct _glist *owner,
707 int xpix, int ypix, int shift, int alt, int dbl, int doit)
708{
709 t_scalar *x = (t_scalar *)z;
710 int hit = 0;
711 t_template *template = template_findbyname(x->sc_template);
712 t_canvas *templatecanvas = template_findcanvas(template);
713 t_gobj *y;
714 float basex, basey;
715 scalar_getbasexy(x, &basex, &basey);
716 for (y = templatecanvas->gl_list; y; y = y->g_next)
717 {
718 t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd);
719 if (!wb) continue;
720 if (hit = (*wb->w_parentclickfn)(y, owner,
721 x, template, basex, basey,
722 xpix, ypix, shift, alt, dbl, doit))
723 return (hit);
724 }
725 return (0);
726}
727
728void canvas_writescalar(t_symbol *templatesym, t_word *w, t_binbuf *b,
729 int amarrayelement);
730
731static void scalar_save(t_gobj *z, t_binbuf *b)
732{
733 t_scalar *x = (t_scalar *)z;
734 t_binbuf *b2 = binbuf_new();
735 t_atom a, *argv;
736 int i, argc;
737 canvas_writescalar(x->sc_template, x->sc_vec, b2, 0);
738 binbuf_addv(b, "ss", &s__X, gensym("scalar"));
739 binbuf_addbinbuf(b, b2);
740 binbuf_addsemi(b);
741 binbuf_free(b2);
742}
743
744static void scalar_properties(t_gobj *z, struct _glist *owner)
745{
746 t_scalar *x = (t_scalar *)z;
747 char *buf, buf2[80];
748 int bufsize;
749 t_binbuf *b;
750 glist_noselect(owner);
751 glist_select(owner, z);
752 b = glist_writetobinbuf(owner, 0);
753 binbuf_gettext(b, &buf, &bufsize);
754 binbuf_free(b);
755 buf = t_resizebytes(buf, bufsize, bufsize+1);
756 buf[bufsize] = 0;
757 sprintf(buf2, "pdtk_data_dialog %%s {");
758 gfxstub_new((t_pd *)owner, x, buf2);
759 sys_gui(buf);
760 sys_gui("}\n");
761 t_freebytes(buf, bufsize+1);
762}
763
764static t_widgetbehavior scalar_widgetbehavior =
765{
766 scalar_getrect,
767 scalar_displace,
768 scalar_select,
769 scalar_activate,
770 scalar_delete,
771 scalar_vis,
772 scalar_click,
773};
774
775static void scalar_free(t_scalar *x)
776{
777 int i;
778 t_dataslot *datatypes, *dt;
779 t_symbol *templatesym = x->sc_template;
780 t_template *template = template_findbyname(templatesym);
781 if (!template)
782 {
783 error("scalar: couldn't find template %s", templatesym->s_name);
784 return;
785 }
786 word_free(x->sc_vec, template);
787 gfxstub_deleteforkey(x);
788 /* the "size" field in the class is zero, so Pd doesn't try to free
789 us automatically (see pd_free()) */
790 freebytes(x, sizeof(t_scalar) + (template->t_n - 1) * sizeof(*x->sc_vec));
791}
792
793/* ----------------- setup function ------------------- */
794
795void g_scalar_setup(void)
796{
797 scalar_class = class_new(gensym("scalar"), 0, (t_method)scalar_free, 0,
798 CLASS_GOBJ, 0);
799 class_setwidget(scalar_class, &scalar_widgetbehavior);
800 class_setsavefn(scalar_class, scalar_save);
801 class_setpropertiesfn(scalar_class, scalar_properties);
802}