Fix pdbox makefile to actually take part in dependency generation
[kugel-rb.git] / apps / plugins / pdbox / PDa / src / g_scalar.c
blobd3809c9bc3af71bffb699809e5444b464cc58da8
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. */
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
7 can contain numbers, sublists, and arrays.
9 Also, the "tscalar" object, an ordinary text object that owns a single "scalar"
10 and draws it on the parent. This is intended as a way that abstractions can
11 control their appearances by adding stuff to draw.
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...
22 #ifdef ROCKBOX
23 #include "plugin.h"
24 #include "../../pdbox.h"
25 #include "m_pd.h"
26 #include "g_canvas.h"
27 #else /* ROCKBOX */
28 #include <stdlib.h>
29 #include <string.h>
30 #include <stdio.h> /* for read/write to files */
31 #include "m_pd.h"
32 #include "g_canvas.h"
33 #endif /* ROCKBOX */
35 t_class *scalar_class;
37 void word_init(t_word *wp, t_template *template, t_gpointer *gp)
39 int i, nitems = template->t_n;
40 t_dataslot *datatypes = template->t_vec;
41 for (i = 0; i < nitems; i++, datatypes++, wp++)
43 int type = datatypes->ds_type;
44 if (type == DT_FLOAT)
45 wp->w_float = 0;
46 else if (type == DT_SYMBOL)
47 wp->w_symbol = &s_symbol;
48 else if (type == DT_ARRAY)
50 wp->w_array = array_new(datatypes->ds_arraytemplate, gp);
52 else if (type == DT_LIST)
54 /* LATER test this and get it to work */
55 wp->w_list = canvas_new(0, 0, 0, 0);
60 void word_restore(t_word *wp, t_template *template,
61 int argc, t_atom *argv)
63 int i, nitems = template->t_n;
64 t_dataslot *datatypes = template->t_vec;
65 for (i = 0; i < nitems; i++, datatypes++, wp++)
67 int type = datatypes->ds_type;
68 if (type == DT_FLOAT)
70 float f;
71 if (argc)
73 f = atom_getfloat(argv);
74 argv++, argc--;
76 else f = 0;
77 wp->w_float = f;
79 else if (type == DT_SYMBOL)
81 t_symbol *s;
82 if (argc)
84 s = atom_getsymbol(argv);
85 argv++, argc--;
87 else s = &s_;
88 wp->w_symbol = s;
91 if (argc)
92 post("warning: word_restore: extra arguments");
95 void word_free(t_word *wp, t_template *template)
97 int i;
98 t_dataslot *dt;
99 for (dt = template->t_vec, i = 0; i < template->t_n; i++, dt++)
101 if (dt->ds_type == DT_ARRAY)
102 array_free(wp[i].w_array);
103 else if (dt->ds_type == DT_LIST)
104 canvas_free(wp[i].w_list);
108 /* make a new scalar and add to the glist. We create a "gp" here which
109 will be used for array items to point back here. This gp doesn't do
110 reference counting or "validation" updates though; the parent won't go away
111 without the contained arrays going away too. The "gp" is copied out
112 by value in the word_init() routine so we can throw our copy away. */
114 t_scalar *scalar_new(t_glist *owner, t_symbol *templatesym)
116 t_scalar *x;
117 t_template *template;
118 t_gpointer gp;
119 gpointer_init(&gp);
120 template = template_findbyname(templatesym);
121 if (!template)
123 error("scalar: couldn't find template %s", templatesym->s_name);
124 return (0);
126 x = (t_scalar *)getbytes(sizeof(t_scalar) +
127 (template->t_n - 1) * sizeof(*x->sc_vec));
128 x->sc_gobj.g_pd = scalar_class;
129 x->sc_template = templatesym;
130 gpointer_setglist(&gp, owner, x);
131 word_init(x->sc_vec, template, &gp);
132 return (x);
135 /* Pd method to create a new scalar, add it to a glist, and initialize
136 it from the message arguments. */
138 int glist_readscalar(t_glist *x, int natoms, t_atom *vec,
139 int *p_nextmsg, int selectit);
141 void glist_scalar(t_glist *glist,
142 t_symbol *classname, t_int argc, t_atom *argv)
144 t_symbol *templatesym =
145 canvas_makebindsym(atom_getsymbolarg(0, argc, argv));
146 t_binbuf *b;
147 int natoms, nextmsg = 0;
148 t_atom *vec;
149 #ifdef ROCKBOX
150 (void) classname;
151 #endif
152 if (!template_findbyname(templatesym))
154 pd_error(glist, "%s: no such template",
155 atom_getsymbolarg(0, argc, argv)->s_name);
156 return;
159 b = binbuf_new();
160 binbuf_restore(b, argc, argv);
161 natoms = binbuf_getnatom(b);
162 vec = binbuf_getvec(b);
164 glist_readscalar(glist, natoms, vec, &nextmsg, 0);
165 binbuf_free(b);
168 /* -------------------- widget behavior for scalar ------------ */
169 void scalar_getbasexy(t_scalar *x, float *basex, float *basey)
171 t_template *template = template_findbyname(x->sc_template);
172 *basex = template_getfloat(template, gensym("x"), x->sc_vec, 0);
173 *basey = template_getfloat(template, gensym("y"), x->sc_vec, 0);
176 static void scalar_getrect(t_gobj *z, t_glist *owner,
177 int *xp1, int *yp1, int *xp2, int *yp2)
179 t_scalar *x = (t_scalar *)z;
180 #ifndef ROCKBOX
181 int hit = 0;
182 #endif
183 t_template *template = template_findbyname(x->sc_template);
184 t_canvas *templatecanvas = template_findcanvas(template);
185 int x1 = 0x7fffffff, x2 = -0x7fffffff, y1 = 0x7fffffff, y2 = -0x7fffffff;
186 t_gobj *y;
187 float basex, basey;
188 scalar_getbasexy(x, &basex, &basey);
189 /* if someone deleted the template canvas, we're just a point */
190 if (!templatecanvas)
192 x1 = x2 = glist_xtopixels(owner, basex);
193 y1 = y2 = glist_ytopixels(owner, basey);
195 else
197 int hit = 0;
198 x1 = y1 = 0x7fffffff;
199 x2 = y2 = -0x7fffffff;
200 for (y = templatecanvas->gl_list; y; y = y->g_next)
202 t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd);
203 int nx1, ny1, nx2, ny2;
204 if (!wb) continue;
205 (*wb->w_parentgetrectfn)(y, owner,
206 x->sc_vec, template, basex, basey,
207 &nx1, &ny1, &nx2, &ny2);
208 if (hit)
210 if (nx1 < x1) x1 = nx1;
211 if (ny1 < y1) y1 = ny1;
212 if (nx2 > x2) x2 = nx2;
213 if (ny2 > y2) y2 = ny2;
215 else x1 = nx1, y1 = ny1, x2 = nx2, y2 = ny2, hit = 1;
217 if (!hit) x1 = y1 = x2 = y2 = 0;
219 /* post("scalar x1 %d y1 %d x2 %d y2 %d", x1, y1, x2, y2); */
220 *xp1 = x1;
221 *yp1 = y1;
222 *xp2 = x2;
223 *yp2 = y2;
226 static void scalar_select(t_gobj *z, t_glist *owner, int state)
228 #ifndef ROCKBOX
229 t_scalar *x = (t_scalar *)z;
230 #endif
231 /* post("scalar_select %d", state); */
232 /* later */
233 if (state)
235 int x1, y1, x2, y2;
236 scalar_getrect(z, owner, &x1, &y1, &x2, &y2);
237 x1--; x2++; y1--; y2++;
238 #ifndef ROCKBOX
239 sys_vgui(".x%x.c create line %d %d %d %d %d %d %d %d %d %d \
240 -width 0 -fill blue -tags select%x\n",
241 glist_getcanvas(owner), x1, y1, x1, y2, x2, y2, x2, y1, x1, y1,
243 #endif
245 #ifndef ROCKBOX
246 else sys_vgui(".x%x.c delete select%x\n", glist_getcanvas(owner), x);
247 #endif
250 static void scalar_displace(t_gobj *z, t_glist *glist, int dx, int dy)
252 t_scalar *x = (t_scalar *)z;
253 t_symbol *templatesym = x->sc_template;
254 t_template *template = template_findbyname(templatesym);
255 t_symbol *zz;
256 int xonset, yonset, xtype, ytype, gotx, goty;
257 if (!template)
259 error("scalar: couldn't find template %s", templatesym->s_name);
260 return;
262 gotx = template_find_field(template, gensym("x"), &xonset, &xtype, &zz);
263 if (gotx && (xtype != DT_FLOAT))
264 gotx = 0;
265 goty = template_find_field(template, gensym("y"), &yonset, &ytype, &zz);
266 if (goty && (ytype != DT_FLOAT))
267 goty = 0;
268 if (gotx)
269 *(t_float *)(((char *)(x->sc_vec)) + xonset) +=
270 dx * (glist_pixelstox(glist, 1) - glist_pixelstox(glist, 0));
271 if (goty)
272 *(t_float *)(((char *)(x->sc_vec)) + yonset) +=
273 dy * (glist_pixelstoy(glist, 1) - glist_pixelstoy(glist, 0));
274 glist_redrawitem(glist, z);
275 if (glist_isselected(glist, z))
277 scalar_select(z, glist, 0);
278 scalar_select(z, glist, 1);
282 static void scalar_activate(t_gobj *z, t_glist *owner, int state)
284 #ifdef ROCKBOX
285 (void) z;
286 (void) owner;
287 (void) state;
288 #endif
289 /* post("scalar_activate %d", state); */
290 /* later */
293 static void scalar_delete(t_gobj *z, t_glist *glist)
295 #ifdef ROCKBOX
296 (void) z;
297 (void) glist;
298 #endif
299 /* nothing to do */
302 static void scalar_vis(t_gobj *z, t_glist *owner, int vis)
304 t_scalar *x = (t_scalar *)z;
305 t_template *template = template_findbyname(x->sc_template);
306 t_canvas *templatecanvas = template_findcanvas(template);
307 t_gobj *y;
308 float basex, basey;
309 scalar_getbasexy(x, &basex, &basey);
310 /* if we don't know how to draw it, make a small rectangle */
311 if (!templatecanvas)
313 if (vis)
315 #ifndef ROCKBOX
316 int x1 = glist_xtopixels(owner, basex);
317 int y1 = glist_ytopixels(owner, basey);
318 sys_vgui(".x%x.c create rectangle %d %d %d %d -tags scalar%x\n",
319 glist_getcanvas(owner), x1-1, y1-1, x1+1, y1+1, x);
320 #endif
322 #ifndef ROCKBOX
323 else sys_vgui(".x%x.c delete scalar%x\n", glist_getcanvas(owner), x);
324 #endif
325 return;
328 for (y = templatecanvas->gl_list; y; y = y->g_next)
330 t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd);
331 if (!wb) continue;
332 (*wb->w_parentvisfn)(y, owner, x->sc_vec, template, basex, basey, vis);
336 static int scalar_click(t_gobj *z, struct _glist *owner,
337 int xpix, int ypix, int shift, int alt, int dbl, int doit)
339 t_scalar *x = (t_scalar *)z;
340 int hit = 0;
341 t_template *template = template_findbyname(x->sc_template);
342 t_canvas *templatecanvas = template_findcanvas(template);
343 t_gobj *y;
344 float basex, basey;
345 scalar_getbasexy(x, &basex, &basey);
346 for (y = templatecanvas->gl_list; y; y = y->g_next)
348 t_parentwidgetbehavior *wb = pd_getparentwidget(&y->g_pd);
349 if (!wb) continue;
350 if((hit = (*wb->w_parentclickfn)(y, owner,
351 x, template, basex, basey,
352 xpix, ypix, shift, alt, dbl, doit)))
353 return (hit);
355 return (0);
358 void canvas_writescalar(t_symbol *templatesym, t_word *w, t_binbuf *b,
359 int amarrayelement);
361 static void scalar_save(t_gobj *z, t_binbuf *b)
363 t_scalar *x = (t_scalar *)z;
364 t_binbuf *b2 = binbuf_new();
365 #ifndef ROCKBOX
366 t_atom a, *argv;
367 int i, argc;
368 #endif
369 canvas_writescalar(x->sc_template, x->sc_vec, b2, 0);
370 binbuf_addv(b, "ss", &s__X, gensym("scalar"));
371 binbuf_addbinbuf(b, b2);
372 binbuf_addsemi(b);
373 binbuf_free(b2);
376 static void scalar_properties(t_gobj *z, struct _glist *owner)
378 #ifdef ROCKBOX
379 (void) z;
380 (void) owner;
381 #else /* ROCKBOX */
382 t_scalar *x = (t_scalar *)z;
383 char *buf, buf2[80];
384 int bufsize;
385 t_binbuf *b;
386 glist_noselect(owner);
387 glist_select(owner, z);
388 b = glist_writetobinbuf(owner, 0);
389 binbuf_gettext(b, &buf, &bufsize);
390 binbuf_free(b);
391 buf = t_resizebytes(buf, bufsize, bufsize+1);
392 buf[bufsize] = 0;
393 sprintf(buf2, "pdtk_data_dialog %%s {");
394 gfxstub_new((t_pd *)owner, x, buf2);
395 sys_gui(buf);
396 sys_gui("}\n");
397 t_freebytes(buf, bufsize+1);
398 #endif /* ROCKBOX */
401 static t_widgetbehavior scalar_widgetbehavior =
403 scalar_getrect,
404 scalar_displace,
405 scalar_select,
406 scalar_activate,
407 scalar_delete,
408 scalar_vis,
409 scalar_click,
412 static void scalar_free(t_scalar *x)
414 #ifndef ROCKBOX
415 int i;
416 t_dataslot *datatypes, *dt;
417 #endif
418 t_symbol *templatesym = x->sc_template;
419 t_template *template = template_findbyname(templatesym);
420 if (!template)
422 error("scalar: couldn't find template %s", templatesym->s_name);
423 return;
425 word_free(x->sc_vec, template);
426 #ifndef ROCKBOX
427 gfxstub_deleteforkey(x);
428 #endif
429 /* the "size" field in the class is zero, so Pd doesn't try to free
430 us automatically (see pd_free()) */
431 freebytes(x, sizeof(t_scalar) + (template->t_n - 1) * sizeof(*x->sc_vec));
434 /* ----------------- setup function ------------------- */
436 void g_scalar_setup(void)
438 scalar_class = class_new(gensym("scalar"), 0, (t_method)scalar_free, 0,
439 CLASS_GOBJ, 0);
440 class_setwidget(scalar_class, &scalar_widgetbehavior);
441 class_setsavefn(scalar_class, scalar_save);
442 class_setpropertiesfn(scalar_class, scalar_properties);