Newer
Older
/* Copyright (c) 1997-1999 Miller Puckette.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* changes by Thomas Musil IEM KUG Graz Austria 2001 */
/* the methods for calling the gui-objects from menu are implemented */
/* all changes are labeled with iemlib */
#include <stdlib.h>
#include "m_pd.h"
#include "m_imp.h"
#include "s_stuff.h"
#include "g_canvas.h"
#include <stdio.h>
#include <string.h>
#include <math.h>
Ivica Bukvic
committed
#include "g_undo.h"
#include "x_preset.h"
#include "s_utf8.h"
Ivica Bukvic
committed
t_class *message_class;
static t_class *gatom_class;
static void text_vis(t_gobj *z, t_glist *glist, int vis);
static void text_displace(t_gobj *z, t_glist *glist,
int dx, int dy);
static void text_getrect(t_gobj *z, t_glist *glist,
int *xp1, int *yp1, int *xp2, int *yp2);
void canvas_howputnew(t_canvas *x, int *connectp, int *xpixp, int *ypixp,
int *indexp, int *totalp);
void canvas_startmotion(t_canvas *x);
t_widgetbehavior text_widgetbehavior;
static char *invalid_fill = "$::pd_colors(dash_fill)";
extern void canvas_displaceselection(t_canvas *x, int dx, int dy);
extern void canvas_apply_setundo(t_canvas *x, t_gobj *y);
extern void canvas_setundo(t_canvas *x, t_undofn undofn, void *buf,
const char *name);
extern void *canvas_undo_set_create(t_canvas *x);
extern void canvas_undo_create(t_canvas *x, void *z, int action);
extern int we_are_undoing;
Ivica Bukvic
committed
extern void glob_preset_node_list_check_loc_and_update(void);
extern void glob_preset_node_list_seek_hub(void);
/* ----------------- the "text" object. ------------------ */
/* add a "text" object (comment) to a glist. While this one goes for any
glist, the other 3 below are for canvases only. (why?) This is called
without args if invoked from the GUI; otherwise at least x and y
are provided. */
void glist_text(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
{
Ivica Bukvic
committed
if (canvas_hasarray(gl)) return;
t_text *x = (t_text *)pd_new(text_class);
t_atom at;
x->te_width = 0; /* don't know it yet. */
x->te_type = T_TEXT;
x->te_iemgui = 0;
x->te_binbuf = binbuf_new();
if (argc > 1)
{
x->te_xpix = atom_getfloatarg(0, argc, argv);
x->te_ypix = atom_getfloatarg(1, argc, argv);
if (argc > 2)
{
Ivica Bukvic
committed
binbuf_restore(x->te_binbuf, argc-2, argv+2);
}
else
{
SETSYMBOL(&at, gensym("comment"));
binbuf_restore(x->te_binbuf, 1, &at);
}
glist_add(gl, &x->te_g);
}
else
{
int connectme, xpix, ypix, indx, nobj;
canvas_howputnew(gl, &connectme, &xpix, &ypix, &indx, &nobj);
pd_vmess((t_pd *)glist_getcanvas(gl), gensym("editmode"), "i", 1);
SETSYMBOL(&at, gensym("comment"));
glist_noselect(gl);
//glist_getnextxy(gl, &xpix, &ypix);
x->te_xpix = xpix;
x->te_ypix = ypix;
binbuf_restore(x->te_binbuf, 1, &at);
glist_add(gl, &x->te_g);
glist_noselect(gl);
glist_select(gl, &x->te_g);
/* it would be nice to "activate" here, but then the second,
"put-me-down" click changes the text selection, which is quite
irritating, so I took this back out. It's OK in messages
and objects though since there's no text in them at menu
creation. */
/* gobj_activate(&x->te_g, gl, 1); */
if (!we_are_undoing)
canvas_undo_add(glist_getcanvas(gl), 9, "create",
(void *)canvas_undo_set_create(glist_getcanvas(gl)));
if (connectme == 0)
{
Ivica Bukvic
committed
canvas_displaceselection(glist_getcanvas(gl), -8, -8);
canvas_startmotion(glist_getcanvas(gl));
}
Ivica Bukvic
committed
glob_preset_node_list_seek_hub();
glob_preset_node_list_check_loc_and_update();
}
/* ----------------- the "object" object. ------------------ */
extern t_pd *newest;
int scalar_in_a_box;
Ivica Bukvic
committed
extern void glist_scalar(t_glist *canvas, t_symbol *s, int argc, t_atom *argv);
void canvas_getargs(int *argcp, t_atom **argvp);
static void canvas_objtext(t_glist *gl, int xpix, int ypix,
int width, int selected,
//fprintf(stderr,"canvas_objtext\n");
Ivica Bukvic
committed
// for hiding arguments
t_atom *vec;
int len, i, hidden;
t_binbuf *hide;
Ivica Bukvic
committed
newest = 0;
canvas_setcurrent((t_canvas *)gl);
canvas_getargs(&argc, &argv);
binbuf_eval(b, &pd_objectmaker, argc, argv);
if (binbuf_getnatom(b))
{
if (!newest)
{
Ivica Bukvic
committed
/* let's see if there's a scalar by this name... */
t_atom *scalar_at = binbuf_getvec(b);
if (scalar_at->a_type == A_SYMBOL)
{
t_symbol *templatesym =
canvas_makebindsym(atom_getsymbol(scalar_at));
t_template *tmpl = template_findbyname(templatesym);
if (template_findbyname(templatesym) &&
template_cancreate(tmpl) &&
template_hasxy(tmpl))
Ivica Bukvic
committed
{
//post("Hmm, found a scalar from struct %s... ",
// templatesym->s_name);
Ivica Bukvic
committed
t_binbuf *scalarbuf = binbuf_new();
t_atom coords_at[2];
SETFLOAT(coords_at, (t_float)xpix);
SETFLOAT(coords_at+1, (t_float)ypix);
binbuf_add(scalarbuf, 1, scalar_at);
binbuf_add(scalarbuf, 2, coords_at);
binbuf_add(scalarbuf, binbuf_getnatom(b)-1, scalar_at+1);
t_atom *scalar_create_at = binbuf_getvec(scalarbuf);
glist_scalar(gl, gensym("scalar_from_canvas_objtext"),
binbuf_getnatom(b)+2, scalar_create_at);
Ivica Bukvic
committed
binbuf_free(scalarbuf);
Ivica Bukvic
committed
canvas_unsetcurrent((t_canvas *)gl);
scalar_in_a_box = 1;
Ivica Bukvic
committed
return;
}
}
binbuf_print(b);
post("... couldn't create");
x = 0;
}
else if (!(x = pd_checkobject(newest)))
{
binbuf_print(b);
post("... didn't return a patchable object");
}
}
else x = 0;
if (!x)
{
/* LATER make the color reflect this */
x = (t_text *)pd_new(text_class);
Ivica Bukvic
committed
//fprintf(stderr,"creating blank object %lx\n", x);
}
/* special case: an object, like preset_hub, hides its arguments
beyond the first n, so we modify its binbuf here */
vec = binbuf_getvec(b);
len = binbuf_getnatom(b);
hidden = 0;
for (i = 0; i < len; i++)
{
if (!strcmp("%hidden%", atom_getsymbol(&vec[i])->s_name))
{
//fprintf(stderr,"found hidden %d %s\n",
// i, atom_getsymbol(&vec[i])->s_name);
hidden = i;
break;
}
}
if (hidden)
{
hide = binbuf_new();
binbuf_add(hide, hidden, vec);
binbuf_free(b);
b = hide;
}
/* done special case */
Ivica Bukvic
committed
Ivica Bukvic
committed
Ivica Bukvic
committed
x->te_width = width;
/* let's see if iemgui objects did not already set the value to 1,
otherwise set it explicitly to 0 */
if (x->te_iemgui != 1)
x->te_iemgui = 0;
Ivica Bukvic
committed
if (selected)
{
/* this is called if we've been created from the menu. */
glist_select(gl, &x->te_g);
gobj_activate(&x->te_g, gl,
2); // <-- hack to signal that we're a new object
}
if (pd_class(&x->ob_pd) == vinlet_class)
canvas_resortinlets(glist_getcanvas(gl));
if (pd_class(&x->ob_pd) == voutlet_class)
canvas_resortoutlets(glist_getcanvas(gl));
canvas_unsetcurrent((t_canvas *)gl);
Ivica Bukvic
committed
glob_preset_node_list_seek_hub();
glob_preset_node_list_check_loc_and_update();
// here we recreate data buffer inside previously created undo snapshot
//canvas_undo_create(glist_getcanvas(gl),
// glist_getcanvas(gl)->u_last->data, UNDO_FREE);
//glist_getcanvas(gl)->u_last->data =
// canvas_undo_set_create(glist_getcanvas(gl));
/*if (binbuf_getnatom(x->te_binbuf) && !we_are_undoing) {
fprintf(stderr,"canvas_objtext calls create undo\n");
//glist_select(gl, &x->te_g);
canvas_undo_add(glist_getcanvas(gl), 9, "create",
(void *)canvas_undo_set_create(glist_getcanvas(gl)));
}*/
if ( glist_isvisible( ((t_canvas *)gl) ) )
{
Mathieu L Bouchard
committed
canvas_getscroll(glist_getcanvas(gl));
Miller Puckette
committed
extern int sys_noautopatch;
Ivica Bukvic
committed
extern t_gobj *glist_nth(t_glist *x, int n);
extern int glist_getindex(t_glist *x, t_gobj *y);
/* utility routine to figure out where to put a new text box from menu
and whether to connect to it automatically */
void canvas_howputnew(t_canvas *x, int *connectp, int *xpixp, int *ypixp,
/*
int connectme = 0;
if (x->gl_editor->e_selection &&
!x->gl_editor->e_selection->sel_next &&
!sys_noautopatch)
{
selected = x->gl_editor->e_selection->sel_what;
t_object *ob = pd_checkobject(&selected->g_pd);
connectme = (obj_noutlets(ob) ? 1 : 0);
}*/
int connectme = (x->gl_editor->e_selection &&
!x->gl_editor->e_selection->sel_next);
t_gobj *g, *selected = x->gl_editor->e_selection->sel_what;
Ivica Bukvic
committed
t_text *t = (t_text *)selected;
int recreate = 0;
// if selected object has not yet been activated we need to recreate it first
if (pd_class(&t->te_pd) == text_class && t->te_type != T_TEXT)
Ivica Bukvic
committed
glist_noselect(x); // we do this to explicitly activate object
glist_select(x, glist_nth(x, glist_getindex(x, 0)-1)); // then reselect it
selected = x->gl_editor->e_selection->sel_what;
recreate = 1;
Ivica Bukvic
committed
for (g = x->gl_list, nobj = 0; g; g = g->g_next, nobj++)
if (g == selected)
{
gobj_getrect(g, x, &x1, &y1, &x2, &y2);
indx = nobj;
*xpixp = x1;
*ypixp = y2 + 5;
}
glist_noselect(x);
/* search back for 'selected' and if it isn't on the list,
plan just to connect from the last item on the list. */
for (g = x->gl_list, n2 = 0; g; g = g->g_next, n2++)
{
if (g == selected)
{
indx = n2;
break;
}
else if (!g->g_next)
indx = nobj-1;
}
x->gl_editor->e_onmotion = MA_NONE;
Mathieu L Bouchard
committed
canvas_getscroll(x);
}
else
{
glist_getnextxy(x, xpixp, ypixp);
glist_noselect(x);
if (sys_noautopatch)
{
if (connectme == 1) connectme = -1;
else connectme = 0;
}
*connectp = connectme;
*indexp = indx;
*totalp = nobj;
}
/* object creation routine. These are called without any arguments if
they're invoked from the gui; when pasting or restoring from a file, we
get at least x and y. */
Ivica Bukvic
committed
EXTERN int connect_exception;
void canvas_obj(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
{
//fprintf(stderr,"canvas_obj\n");
Ivica Bukvic
committed
if (canvas_hasarray(gl)) return;
if (argc >= 2)
{
t_binbuf *b = binbuf_new();
binbuf_restore(b, argc-2, argv+2);
canvas_objtext(gl, atom_getintarg(0, argc, argv),
Ivica Bukvic
committed
atom_getintarg(1, argc, argv), 0, 0, b);
/* JMZ: don't go into interactive mode in a closed canvas */
else if (!glist_isvisible(gl))
post("unable to create stub object in closed canvas!");
else
{
/* interactively create new obect */
int connectme, xpix, ypix, indx, nobj;
canvas_howputnew(gl, &connectme, &xpix, &ypix, &indx, &nobj);
pd_vmess(&gl->gl_pd, gensym("editmode"), "i", 1);
canvas_objtext(gl,
connectme ? xpix : xpix - 8,
connectme ? ypix : ypix - 8,
0, 1, b);
if (connectme == 1)
{
//fprintf(stderr,"canvas_obj calls canvas_connect\n");
connect_exception = 1;
connect_exception = 0;
}
else if (connectme == 0)
{
//fprintf(stderr,"canvas_obj calls canvas_startmotion\n");
// canvas_displaceselection(glist_getcanvas(gl), -8, -8);
canvas_startmotion(glist_getcanvas(gl));
}
//canvas_setundo(glist_getcanvas(gl),
// canvas_undo_create, canvas_undo_set_create(gl), "create");
if (!we_are_undoing)
canvas_undo_add(glist_getcanvas(gl), 9, "create",
(void *)canvas_undo_set_create(glist_getcanvas(gl)));
extern void glist_setlastxy(t_glist *gl, int xval, int yval);
/* invoked from tcl/tk: abstraction_name x_offset y_offset */
void canvas_obj_abstraction_from_menu(t_glist *gl, t_symbol *s,
int argc, t_atom *argv)
{
Ivica Bukvic
committed
if (canvas_hasarray(gl)) return;
//fprintf(stderr,"canvas_abstraction_from_menu\n");
//t_text *x;
t_gobj *y;
t_binbuf *b = binbuf_new();
binbuf_restore(b, 2, argv);
int connectme, xpix, ypix, indx, nobj;
canvas_howputnew(gl, &connectme, &xpix, &ypix, &indx, &nobj);
pd_vmess(&gl->gl_pd, gensym("editmode"), "i", 1);
if (sys_k12_mode)
pd_vmess (&gl->gl_pd, gensym("tooltips"), "i", 1);
canvas_objtext(gl, xpix+atom_getintarg(1, argc, argv),
ypix+atom_getintarg(2, argc, argv), 0, 1, b);
// the object is now the last on the glist so we locate it
// and send it loadbang
// we know we have at least one object since we just created one
// so we don't check for y being valid
y = gl->gl_list;
while (y->g_next)
y = y->g_next;
canvas_loadbang((t_canvas *)y);
if (connectme == 1)
{
canvas_connect(gl, indx, 0, nobj, 0);
}
else if (connectme == 0)
{
Ivica Bukvic
committed
//glist_setlastxy(glist_getcanvas(gl), xpix, ypix);
canvas_startmotion(glist_getcanvas(gl));
}
canvas_undo_add(glist_getcanvas(gl), 9, "create",
(void *)canvas_undo_set_create(glist_getcanvas(gl)));
}
/* make an object box for an object that's already there. */
/* iemlib */
void canvas_iemguis(t_glist *gl, t_symbol *guiobjname)
{
Ivica Bukvic
committed
if (canvas_hasarray(gl)) return;
//fprintf(stderr,"canvas_iemguis\n");
if(!strcmp(guiobjname->s_name, "cnv"))
glist_noselect(gl);
int connectme, xpix, ypix, indx, nobj;
canvas_howputnew(gl, &connectme, &xpix, &ypix, &indx, &nobj);
/* NOT NECESSARY ANY MORE: compensate for the iemgui sliders' xyoffset
in case of autopatch
if (connectme)
{
if(!strcmp(guiobjname->s_name, "hsl"))
xpix = xpix + 3;
else if(!strcmp(guiobjname->s_name, "vsl"))
ypix = ypix + 2;
else if(!strcmp(guiobjname->s_name, "vu"))
{
xpix = xpix + 1;
ypix = ypix + 2;
}
}*/
pd_vmess(&gl->gl_pd, gensym("editmode"), "i", 1);
glist_noselect(gl);
SETSYMBOL(&at, guiobjname);
binbuf_restore(b, 1, &at);
canvas_objtext(gl, xpix, ypix, 0, 1, b);
if (connectme == 1)
canvas_connect(gl, indx, 0, nobj, 0);
//glist_getnextxy(gl, &xpix, &ypix);
//canvas_objtext(gl, xpix, ypix, 1, b);
else if (connectme == 0)
{
Ivica Bukvic
committed
canvas_displaceselection(glist_getcanvas(gl), -8, -8);
canvas_startmotion(glist_getcanvas(gl));
}
//canvas_setundo(glist_getcanvas(gl),
// canvas_undo_create, canvas_undo_set_create(gl), "create");
canvas_undo_add(glist_getcanvas(gl), 9, "create",
(void *)canvas_undo_set_create(glist_getcanvas(gl)));
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
}
void canvas_bng(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
{
canvas_iemguis(gl, gensym("bng"));
}
void canvas_toggle(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
{
canvas_iemguis(gl, gensym("tgl"));
}
void canvas_vslider(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
{
canvas_iemguis(gl, gensym("vsl"));
}
void canvas_hslider(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
{
canvas_iemguis(gl, gensym("hsl"));
}
void canvas_hdial(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
{
canvas_iemguis(gl, gensym("hdl"));
}
void canvas_vdial(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
{
canvas_iemguis(gl, gensym("vdl"));
}
void canvas_hradio(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
{
canvas_iemguis(gl, gensym("hradio"));
}
void canvas_vradio(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
{
canvas_iemguis(gl, gensym("vradio"));
}
void canvas_vumeter(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
{
canvas_iemguis(gl, gensym("vu"));
}
void canvas_mycnv(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
{
canvas_iemguis(gl, gensym("cnv"));
}
void canvas_numbox(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
{
canvas_iemguis(gl, gensym("nbx"));
}
/* iemlib */
void canvas_objfor(t_glist *gl, t_text *x, int argc, t_atom *argv)
{
x->te_width = 0; /* don't know it yet. */
x->te_type = T_OBJECT;
x->te_binbuf = binbuf_new();
x->te_xpix = atom_getfloatarg(0, argc, argv);
x->te_ypix = atom_getfloatarg(1, argc, argv);
if (argc > 2) binbuf_restore(x->te_binbuf, argc-2, argv+2);
glist_add(gl, &x->te_g);
}
/* ---------------------- the "message" text item ------------------------ */
typedef struct _messresponder
{
t_pd mr_pd;
t_outlet *mr_outlet;
} t_messresponder;
typedef struct _message
{
t_text m_text;
t_messresponder m_messresponder;
t_glist *m_glist;
t_clock *m_clock;
} t_message;
static t_class *messresponder_class;
static void messresponder_bang(t_messresponder *x)
{
outlet_bang(x->mr_outlet);
}
static void messresponder_float(t_messresponder *x, t_float f)
{
outlet_float(x->mr_outlet, f);
}
static void messresponder_symbol(t_messresponder *x, t_symbol *s)
{
outlet_symbol(x->mr_outlet, s);
}
static void messresponder_blob(t_messresponder *x, t_blob *st)
{ /* MP 20070107 blob type */
outlet_blob(x->mr_outlet, st);
}
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
static void messresponder_list(t_messresponder *x,
t_symbol *s, int argc, t_atom *argv)
{
outlet_list(x->mr_outlet, s, argc, argv);
}
static void messresponder_anything(t_messresponder *x,
t_symbol *s, int argc, t_atom *argv)
{
outlet_anything(x->mr_outlet, s, argc, argv);
}
static void message_bang(t_message *x)
{
binbuf_eval(x->m_text.te_binbuf, &x->m_messresponder.mr_pd, 0, 0);
}
static void message_float(t_message *x, t_float f)
{
t_atom at;
SETFLOAT(&at, f);
binbuf_eval(x->m_text.te_binbuf, &x->m_messresponder.mr_pd, 1, &at);
}
static void message_symbol(t_message *x, t_symbol *s)
{
t_atom at;
SETSYMBOL(&at, s);
binbuf_eval(x->m_text.te_binbuf, &x->m_messresponder.mr_pd, 1, &at);
}
static void message_blob(t_message *x, t_blob *st)
{
t_atom at;
SETBLOB(&at, st);
binbuf_eval(x->m_text.te_binbuf, &x->m_messresponder.mr_pd, 1, &at);
}
static void message_list(t_message *x, t_symbol *s, int argc, t_atom *argv)
{
Ivica Bukvic
committed
// TODO: here and elsewhere in the message, do we want $0 to be parsed
// into canvas instance? Makes sense since there is no such argument,
// but will this break anything?
//canvas_setcurrent(x->m_glist);
binbuf_eval(x->m_text.te_binbuf, &x->m_messresponder.mr_pd, argc, argv);
Ivica Bukvic
committed
//canvas_unsetcurrent(x->m_glist);
}
static void message_set(t_message *x, t_symbol *s, int argc, t_atom *argv)
{
binbuf_clear(x->m_text.te_binbuf);
binbuf_add(x->m_text.te_binbuf, argc, argv);
glist_retext(x->m_glist, &x->m_text);
Ivica Bukvic
committed
if (glist_isvisible(glist_getcanvas(x->m_glist)))
Mathieu L Bouchard
committed
canvas_getscroll(x->m_glist);
}
static void message_add2(t_message *x, t_symbol *s, int argc, t_atom *argv)
{
binbuf_add(x->m_text.te_binbuf, argc, argv);
glist_retext(x->m_glist, &x->m_text);
Ivica Bukvic
committed
if (glist_isvisible(glist_getcanvas(x->m_glist)))
Mathieu L Bouchard
committed
canvas_getscroll(x->m_glist);
}
static void message_add(t_message *x, t_symbol *s, int argc, t_atom *argv)
{
binbuf_add(x->m_text.te_binbuf, argc, argv);
binbuf_addsemi(x->m_text.te_binbuf);
glist_retext(x->m_glist, &x->m_text);
Ivica Bukvic
committed
if (glist_isvisible(glist_getcanvas(x->m_glist)))
Mathieu L Bouchard
committed
canvas_getscroll(x->m_glist);
}
static void message_addcomma(t_message *x)
{
t_atom a;
SETCOMMA(&a);
binbuf_add(x->m_text.te_binbuf, 1, &a);
glist_retext(x->m_glist, &x->m_text);
Ivica Bukvic
committed
if (glist_isvisible(glist_getcanvas(x->m_glist)))
Mathieu L Bouchard
committed
canvas_getscroll(x->m_glist);
}
static void message_addsemi(t_message *x)
{
message_add(x, 0, 0, 0);
Ivica Bukvic
committed
if (glist_isvisible(glist_getcanvas(x->m_glist)))
Mathieu L Bouchard
committed
canvas_getscroll(x->m_glist);
}
static void message_adddollar(t_message *x, t_floatarg f)
{
t_atom a;
int n = f;
if (n < 0)
n = 0;
SETDOLLAR(&a, n);
binbuf_add(x->m_text.te_binbuf, 1, &a);
glist_retext(x->m_glist, &x->m_text);
Ivica Bukvic
committed
if (glist_isvisible(glist_getcanvas(x->m_glist)))
Mathieu L Bouchard
committed
canvas_getscroll(x->m_glist);
}
static void message_adddollsym(t_message *x, t_symbol *s)
{
t_atom a;
char buf[MAXPDSTRING];
buf[0] = '$';
strncpy(buf+1, s->s_name, MAXPDSTRING-2);
buf[MAXPDSTRING-1] = 0;
SETDOLLSYM(&a, gensym(buf));
binbuf_add(x->m_text.te_binbuf, 1, &a);
glist_retext(x->m_glist, &x->m_text);
Ivica Bukvic
committed
if (glist_isvisible(glist_getcanvas(x->m_glist)))
Mathieu L Bouchard
committed
canvas_getscroll(x->m_glist);
}
static void message_click(t_message *x,
t_floatarg xpos, t_floatarg ypos, t_floatarg shift,
t_floatarg ctrl, t_floatarg alt)
{
message_float(x, 0);
if (glist_isvisible(x->m_glist))
{
t_rtext *y = glist_findrtext(x->m_glist, &x->m_text);
//sys_vgui(".x%lx.c itemconfigure %sR -strokewidth 5\n",
// glist_getcanvas(x->m_glist), rtext_gettag(y));
gui_vmess("gui_message_flash", "xsi",
glist_getcanvas(x->m_glist),
clock_delay(x->m_clock, 120);
}
}
static void message_tick(t_message *x)
{
if (glist_isvisible(x->m_glist))
{
t_rtext *y = glist_findrtext(x->m_glist, &x->m_text);
//sys_vgui(".x%lx.c itemconfigure %sR -strokewidth 1\n",
// glist_getcanvas(x->m_glist), rtext_gettag(y));
gui_vmess("gui_message_flash", "xsi",
glist_getcanvas(x->m_glist),
}
}
static void message_free(t_message *x)
{
clock_free(x->m_clock);
}
t_pd *pd_mess_from_responder(t_pd *x)
{
if (pd_class(x) == messresponder_class)
{
/* do pointer math to try to get to the container message struct */
void *tmp = (void *)x - sizeof(t_text);
/* if it looks like a message, it must be a message */
if(((t_text *)tmp)->te_pd == message_class)
return ((t_pd *)tmp);
}
return x;
}
void canvas_msg(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
{
Ivica Bukvic
committed
if (canvas_hasarray(gl)) return;
/*fprintf(stderr,"canvas_msg\n");
int i = 0;
while(i < argc)
{
if (argv[i].a_type == A_FLOAT)
fprintf(stderr," %f", atom_getfloatarg(i, argc, argv));
else
fprintf(stderr," %s", atom_getsymbolarg(i, argc, argv)->s_name);
i++;
}
fprintf(stderr,"\n");*/
t_message *x = (t_message *)pd_new(message_class);
x->m_messresponder.mr_pd = messresponder_class;
x->m_messresponder.mr_outlet = outlet_new(&x->m_text, &s_float);
x->m_text.te_width = 0; /* don't know it yet. */
x->m_text.te_type = T_MESSAGE;
x->m_text.te_iemgui = 0;
x->m_text.te_binbuf = binbuf_new();
x->m_glist = gl;
x->m_clock = clock_new(x, (t_method)message_tick);
if (argc > 1)
{
x->m_text.te_xpix = atom_getfloatarg(0, argc, argv);
x->m_text.te_ypix = atom_getfloatarg(1, argc, argv);
if (argc > 2) binbuf_restore(x->m_text.te_binbuf, argc-2, argv+2);
glist_add(gl, &x->m_text.te_g);
}
else if (!glist_isvisible(gl))
post("unable to create stub message in closed canvas!");
int connectme, xpix, ypix, indx, nobj;
canvas_howputnew(gl, &connectme, &xpix, &ypix, &indx, &nobj);
pd_vmess(&gl->gl_pd, gensym("editmode"), "i", 1);
x->m_text.te_xpix = xpix;
x->m_text.te_ypix = ypix;
glist_add(gl, &x->m_text.te_g);
glist_noselect(gl);
glist_select(gl, &x->m_text.te_g);
gobj_activate(&x->m_text.te_g, gl,
2); // <-- hack to signal we're a new message box
if (connectme == 1)
else if (connectme == 0)
{
Ivica Bukvic
committed
canvas_displaceselection(glist_getcanvas(gl), -8, -8);
canvas_startmotion(glist_getcanvas(gl));
}
//canvas_setundo(glist_getcanvas(gl),
// canvas_undo_create, canvas_undo_set_create(gl), "create");
canvas_undo_add(glist_getcanvas(gl), 9, "create",
(void *)canvas_undo_set_create(glist_getcanvas(gl)));
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
}
}
/* ---------------------- the "atom" text item ------------------------ */
#define ATOMBUFSIZE 40
#define ATOM_LABELLEFT 0
#define ATOM_LABELRIGHT 1
#define ATOM_LABELUP 2
#define ATOM_LABELDOWN 3
typedef struct _gatom
{
t_text a_text;
t_atom a_atom; /* this holds the value and the type */
t_glist *a_glist; /* owning glist */
t_float a_toggle; /* value to toggle to */
t_float a_draghi; /* high end of drag range */
t_float a_draglo; /* low end of drag range */
t_symbol *a_label; /* symbol to show as label next to box */
t_symbol *a_symfrom; /* "receive" name -- bind ourselvs to this */
t_symbol *a_symto; /* "send" name -- send to this on output */
char a_buf[ATOMBUFSIZE];/* string buffer for typing */
char a_shift; /* was shift key down when dragging started? */
char a_wherelabel; /* 0-3 for left, right, above, below */
t_symbol *a_expanded_to; /* a_symto after $0, $1, ... expansion */
} t_gatom;
/* prepend "-" as necessary to avoid empty strings, so we can
use them in Pd messages. A more complete solution would be
to introduce some quoting mechanism; but then we'd be much more
complicated. */
static t_symbol *gatom_escapit(t_symbol *s)
{
if (!*s->s_name)
return (gensym("-"));
else if (*s->s_name == '-')
{
char shmo[100];
shmo[0] = '-';
strncpy(shmo+1, s->s_name, 99);
shmo[99] = 0;
return (gensym(shmo));
}
else return (iemgui_dollar2raute(s));
}
/* undo previous operation: strip leading "-" if found. */
static t_symbol *gatom_unescapit(t_symbol *s)
{
if (*s->s_name == '-')
return (gensym(s->s_name+1));
else return (iemgui_raute2dollar(s));
}
static void gatom_redraw(t_gobj *client, t_glist *glist)
{
t_gatom *x = (t_gatom *)client;
glist_retext(x->a_glist, &x->a_text);
}
/* recolor option offers 0 ignore recolor
1 recolor */
Ivica Bukvic
committed
static void gatom_retext(t_gatom *x, int senditup, int recolor)
{
t_canvas *canvas = glist_getcanvas(x->a_glist);
t_rtext *y = glist_findrtext(x->a_glist, &x->a_text);
if (recolor)
{
//sys_vgui(".x%lx.c itemconfigure %s -fill %s\n", canvas,
// rtext_gettag(y), "$pd_colors(text)");
}
binbuf_clear(x->a_text.te_binbuf);
binbuf_add(x->a_text.te_binbuf, 1, &x->a_atom);
if (senditup && glist_isvisible(x->a_glist))
sys_queuegui(x, x->a_glist, gatom_redraw);
}
static void gatom_set(t_gatom *x, t_symbol *s, int argc, t_atom *argv)
{
t_atom oldatom = x->a_atom;
int changed = 0;
if (!argc) return;
if (x->a_atom.a_type == A_FLOAT)
x->a_atom.a_w.w_float = atom_getfloat(argv),
changed = (x->a_atom.a_w.w_float != oldatom.a_w.w_float);
else if (x->a_atom.a_type == A_SYMBOL)
x->a_atom.a_w.w_symbol = atom_getsymbol(argv),
changed = (x->a_atom.a_w.w_symbol != oldatom.a_w.w_symbol);
if (changed)
Ivica Bukvic
committed
{
if (x->a_atom.a_type == A_FLOAT && x->a_text.te_width == 1)
gatom_retext(x, 1, 1);
else
gatom_retext(x, 1, 0);
}
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
x->a_buf[0] = 0;
}
static void gatom_bang(t_gatom *x)
{
if (x->a_atom.a_type == A_FLOAT)
{
if (x->a_text.te_outlet)
outlet_float(x->a_text.te_outlet, x->a_atom.a_w.w_float);
if (*x->a_expanded_to->s_name && x->a_expanded_to->s_thing)
{
if (x->a_symto == x->a_symfrom)
pd_error(x,
"%s: atom with same send/receive name (infinite loop)",
x->a_symto->s_name);
else pd_float(x->a_expanded_to->s_thing, x->a_atom.a_w.w_float);
}
}
else if (x->a_atom.a_type == A_SYMBOL)
{
if (x->a_text.te_outlet)
outlet_symbol(x->a_text.te_outlet, x->a_atom.a_w.w_symbol);
if (*x->a_symto->s_name && x->a_expanded_to->s_thing)
{
if (x->a_symto == x->a_symfrom)
pd_error(x,
"%s: atom with same send/receive name (infinite loop)",
x->a_symto->s_name);
else pd_symbol(x->a_expanded_to->s_thing, x->a_atom.a_w.w_symbol);
}
}
}
static void gatom_float(t_gatom *x, t_float f)
{
t_atom at;
SETFLOAT(&at, f);
gatom_set(x, 0, 1, &at);
gatom_bang(x);
}
static void gatom_clipfloat(t_gatom *x, t_float f)
{
if (x->a_draglo != 0 || x->a_draghi != 0)
{
if (f < x->a_draglo)
f = x->a_draglo;
if (f > x->a_draghi)
f = x->a_draghi;
}
gatom_float(x, f);
}
static void gatom_symbol(t_gatom *x, t_symbol *s)
{
t_atom at;
SETSYMBOL(&at, s);
gatom_set(x, 0, 1, &at);
gatom_bang(x);
}
/* We need a list method because, since there's both an "inlet" and a
"nofirstin" flag, the standard list behavior gets confused. */
static void gatom_list(t_gatom *x, t_symbol *s, int argc, t_atom *argv)
{
if (!argc)
gatom_bang(x);
else if (argv->a_type == A_FLOAT)
gatom_float(x, argv->a_w.w_float);
else if (argv->a_type == A_SYMBOL)
gatom_symbol(x, argv->a_w.w_symbol);
else pd_error(x, "gatom_list: need float or symbol");
}
static void gatom_motion(void *z, t_floatarg dx, t_floatarg dy)
{
t_gatom *x = (t_gatom *)z;
if (dy == 0) return;
if (x->a_atom.a_type == A_FLOAT)
{
if (x->a_shift)
{
double nval = x->a_atom.a_w.w_float - 0.01 * dy;
double trunc = 0.01 * (floor(100. * nval + 0.5));
if (trunc < nval + 0.0001 && trunc > nval - 0.0001) nval = trunc;
gatom_clipfloat(x, nval);
}
else
{
double nval = x->a_atom.a_w.w_float - dy;
double trunc = 0.01 * (floor(100. * nval + 0.5));
if (trunc < nval + 0.0001 && trunc > nval - 0.0001) nval = trunc;
trunc = floor(nval + 0.5);
if (trunc < nval + 0.001 && trunc > nval - 0.001) nval = trunc;
gatom_clipfloat(x, nval);
}
}
}
static void gatom_key(void *z, t_floatarg f)
{
//fprintf(stderr,"gatom_key %f\n", f);
t_gatom *x = (t_gatom *)z;
int c = f;
int len = strlen(x->a_buf);
t_atom at;
char sbuf[ATOMBUFSIZE + 4];
if (c == 0)
{
/* we're being notified that no more keys will come for this grab */
if (x->a_buf[0])
Ivica Bukvic
committed
gatom_retext(x, 1, 1);
else
gatom_retext(x, 0, 1);
return;
}
else if (c == '\b')
{
if (len > 0)
x->a_buf[len-1] = 0;
goto redraw;
}
else if (c == '\n')
{
if (x->a_atom.a_type == A_FLOAT)
x->a_atom.a_w.w_float = atof(x->a_buf);
else if (x->a_atom.a_type == A_SYMBOL)
x->a_atom.a_w.w_symbol = gensym(x->a_buf);
else bug("gatom_key");
gatom_bang(x);
Ivica Bukvic
committed
gatom_retext(x, 1, 1);
Ivica Bukvic
committed
glist_grab(x->a_glist, 0, 0, 0, 0, 0);
}
else if (len < (ATOMBUFSIZE-1))
{
/* for numbers, only let reasonable characters through */
if ((x->a_atom.a_type == A_SYMBOL) ||
(c >= '0' && c <= '9' || c == '.' || c == '-'
|| c == 'e' || c == 'E'))
{
/* the wchar could expand to up to 4 bytes, which
* which might overrun our a_buf;
* therefore we first expand into a temporary buffer,
* and only if the resulting utf8 string fits into a_buf
* we apply it
*/
char utf8[UTF8_MAXBYTES];
int utf8len = u8_wc_toutf8(utf8, c);
if((len+utf8len) < (ATOMBUFSIZE-1))
{
int j=0;
for(j=0; j<utf8len; j++)
x->a_buf[len+j] = utf8[j];
x->a_buf[len+utf8len] = 0;
}
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
goto redraw;
}
}
return;
redraw:
/* LATER figure out how to avoid creating all these symbols! */
sprintf(sbuf, "%s...", x->a_buf);
SETSYMBOL(&at, gensym(sbuf));
binbuf_clear(x->a_text.te_binbuf);
binbuf_add(x->a_text.te_binbuf, 1, &at);
glist_retext(x->a_glist, &x->a_text);
}
static void gatom_click(t_gatom *x,
t_floatarg xpos, t_floatarg ypos, t_floatarg shift, t_floatarg ctrl,
t_floatarg alt)
{
if (x->a_text.te_width == 1)
{
if (x->a_atom.a_type == A_FLOAT)
gatom_float(x, (x->a_atom.a_w.w_float == 0));
}
else
{
if (alt)
{
if (x->a_atom.a_type != A_FLOAT) return;
if (x->a_atom.a_w.w_float != 0)
{
x->a_toggle = x->a_atom.a_w.w_float;
gatom_float(x, 0);
}
else gatom_float(x, x->a_toggle);
Ivica Bukvic
committed
gatom_retext(x, 0, 1);
return;
}
x->a_shift = shift;
x->a_buf[0] = 0;
glist_grab(x->a_glist, &x->a_text.te_g, gatom_motion, gatom_key,
xpos, ypos);
}
}
Ivica Bukvic
committed
EXTERN int glist_getindex(t_glist *x, t_gobj *y);
EXTERN int canvas_apply_restore_original_position(t_canvas *x, int pos);
/* message back from dialog window */
static void gatom_param(t_gatom *x, t_symbol *sel, int argc, t_atom *argv)
{
canvas_apply_setundo(x->a_glist, (t_gobj *)x);
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
t_float width = atom_getfloatarg(0, argc, argv);
t_float draglo = atom_getfloatarg(1, argc, argv);
t_float draghi = atom_getfloatarg(2, argc, argv);
t_symbol *label = gatom_unescapit(atom_getsymbolarg(3, argc, argv));
t_float wherelabel = atom_getfloatarg(4, argc, argv);
t_symbol *symfrom = gatom_unescapit(atom_getsymbolarg(5, argc, argv));
t_symbol *symto = gatom_unescapit(atom_getsymbolarg(6, argc, argv));
gobj_vis(&x->a_text.te_g, x->a_glist, 0);
if (!*symfrom->s_name && *x->a_symfrom->s_name)
inlet_new(&x->a_text, &x->a_text.te_pd, 0, 0);
else if (*symfrom->s_name && !*x->a_symfrom->s_name && x->a_text.te_inlet)
{
canvas_deletelinesforio(x->a_glist, &x->a_text,
x->a_text.te_inlet, 0);
inlet_free(x->a_text.te_inlet);
}
if (!*symto->s_name && *x->a_symto->s_name)
outlet_new(&x->a_text, 0);
else if (*symto->s_name && !*x->a_symto->s_name && x->a_text.te_outlet)
{
canvas_deletelinesforio(x->a_glist, &x->a_text,
0, x->a_text.te_outlet);
outlet_free(x->a_text.te_outlet);
}
if (draglo >= draghi)
draglo = draghi = 0;
x->a_draglo = draglo;
x->a_draghi = draghi;
if (width < 0)
width = 4;
else if (width > 80)
width = 80;
x->a_text.te_width = width;
x->a_wherelabel = ((int)wherelabel & 3);
x->a_label = label;
if (*x->a_symfrom->s_name)
pd_unbind(&x->a_text.te_pd,
canvas_realizedollar(x->a_glist, x->a_symfrom));
x->a_symfrom = symfrom;
if (*x->a_symfrom->s_name)
pd_bind(&x->a_text.te_pd,
canvas_realizedollar(x->a_glist, x->a_symfrom));
x->a_symto = symto;
x->a_expanded_to = canvas_realizedollar(x->a_glist, x->a_symto);
gobj_vis(&x->a_text.te_g, x->a_glist, 1);
gobj_select(&x->a_text.te_g, x->a_glist, 1);
Mathieu L Bouchard
committed
canvas_getscroll(x->a_glist);
/* glist_retext(x->a_glist, &x->a_text); */
}
/* ---------------- gatom-specific widget functions --------------- */
static void gatom_getwherelabel(t_gatom *x, t_glist *glist, int *xp, int *yp)
{
int x1, y1, x2, y2;
text_getrect(&x->a_text.te_g, glist, &x1, &y1, &x2, &y2);
if (x->a_wherelabel == ATOM_LABELLEFT)
{
strlen(canvas_realizedollar(x->a_glist, x->a_label)->s_name) *
sys_fontwidth(glist_getfont(glist));
}
else if (x->a_wherelabel == ATOM_LABELRIGHT)
{
}
else if (x->a_wherelabel == ATOM_LABELUP)
{
*xp = -1;
*yp = y2 - y1 + sys_fontheight(glist_getfont(glist));
static void gatom_displace(t_gobj *z, t_glist *glist,
int dx, int dy)
{
//fprintf(stderr,"gatom_displace\n");
t_gatom *x = (t_gatom*)z;
text_displace(z, glist, dx, dy);
if (glist_isvisible(glist))
{
//sys_vgui(".x%lx.c move %lx.l %d %d\n", glist_getcanvas(glist),
// x, dx, dy);
static void gatom_vis(t_gobj *z, t_glist *glist, int vis)
{
//fprintf(stderr,"gatom_vis\n");
t_gatom *x = (t_gatom*)z;
text_vis(z, glist, vis);
if (*x->a_label->s_name)
{
if (vis)
{
int x1, y1;
//sys_vgui("pdtk_text_new .x%lx.c %lx.l %f %f {%s} %d %s\n",
// glist_getcanvas(glist), x,
// (double)x1, (double)y1,
// canvas_realizedollar(x->a_glist, x->a_label)->s_name,
// sys_hostfontsize(glist_getfont(glist)),
// "$pd_colors(text)");
gui_vmess("gui_text_new", "xssiiisi",
glist_getcanvas(glist),
rtext_gettag(y),
"gatom",
0,
x1, // left margin
y1, // top margin
canvas_realizedollar(x->a_glist, x->a_label)->s_name,
sys_hostfontsize(glist_getfont(glist))
);
else
{
/* We're just deleting the parent gobj in the GUI, which takes
care of removing all the children. So we don't need to send
a message here */
//sys_vgui(".x%lx.c delete %lx.l\n", glist_getcanvas(glist), x);
}
}
if (!vis)
sys_unqueuegui(x);
}
void canvas_atom(t_glist *gl, t_atomtype type,
t_symbol *s, int argc, t_atom *argv)
{
Ivica Bukvic
committed
if (canvas_hasarray(gl)) return;
//fprintf(stderr,"canvas_atom\n");
t_gatom *x = (t_gatom *)pd_new(gatom_class);
t_atom at;
x->a_text.te_width = 0; /* don't know it yet. */
x->a_text.te_type = T_ATOM;
x->a_text.te_iemgui = 0;
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
x->a_text.te_binbuf = binbuf_new();
x->a_glist = gl;
x->a_atom.a_type = type;
x->a_toggle = 1;
x->a_draglo = 0;
x->a_draghi = 0;
x->a_wherelabel = 0;
x->a_label = &s_;
x->a_symfrom = &s_;
x->a_symto = x->a_expanded_to = &s_;
if (type == A_FLOAT)
{
x->a_atom.a_w.w_float = 0;
x->a_text.te_width = 5;
SETFLOAT(&at, 0);
}
else
{
x->a_atom.a_w.w_symbol = &s_symbol;
x->a_text.te_width = 10;
SETSYMBOL(&at, &s_symbol);
}
binbuf_add(x->a_text.te_binbuf, 1, &at);
if (argc > 1)
/* create from file. x, y, width, low-range, high-range, flags,
label, receive-name, send-name */
{
x->a_text.te_xpix = atom_getfloatarg(0, argc, argv);
x->a_text.te_ypix = atom_getfloatarg(1, argc, argv);
x->a_text.te_width = atom_getintarg(2, argc, argv);
/* sanity check because some very old patches have trash in this
field... remove this in 2003 or so: */
if (x->a_text.te_width < 0 || x->a_text.te_width > 500)
x->a_text.te_width = 4;
x->a_draglo = atom_getfloatarg(3, argc, argv);
x->a_draghi = atom_getfloatarg(4, argc, argv);
x->a_wherelabel = (((int)atom_getfloatarg(5, argc, argv)) & 3);
x->a_label = gatom_unescapit(atom_getsymbolarg(6, argc, argv));
x->a_symfrom = gatom_unescapit(atom_getsymbolarg(7, argc, argv));
if (*x->a_symfrom->s_name)
pd_bind(&x->a_text.te_pd,
canvas_realizedollar(x->a_glist, x->a_symfrom));
x->a_symto = gatom_unescapit(atom_getsymbolarg(8, argc, argv));
x->a_expanded_to = canvas_realizedollar(x->a_glist, x->a_symto);
if (x->a_symto == &s_)
outlet_new(&x->a_text,
x->a_atom.a_type == A_FLOAT ? &s_float: &s_symbol);
if (x->a_symfrom == &s_)
inlet_new(&x->a_text, &x->a_text.te_pd, 0, 0);
glist_add(gl, &x->a_text.te_g);
}
else
{
int connectme, xpix, ypix, indx, nobj;
canvas_howputnew(gl, &connectme, &xpix, &ypix, &indx, &nobj);
outlet_new(&x->a_text,
x->a_atom.a_type == A_FLOAT ? &s_float: &s_symbol);
inlet_new(&x->a_text, &x->a_text.te_pd, 0, 0);
pd_vmess(&gl->gl_pd, gensym("editmode"), "i", 1);
x->a_text.te_xpix = xpix;
x->a_text.te_ypix = ypix;
glist_add(gl, &x->a_text.te_g);
glist_noselect(gl);
glist_select(gl, &x->a_text.te_g);
if (connectme == 1)
else if (connectme == 0)
{
Ivica Bukvic
committed
canvas_displaceselection(glist_getcanvas(gl), -8, -8);
canvas_startmotion(glist_getcanvas(gl));
}
//canvas_setundo(glist_getcanvas(gl),
// canvas_undo_create, canvas_undo_set_create(gl), "create");
canvas_undo_add(glist_getcanvas(gl), 9, "create",
(void *)canvas_undo_set_create(glist_getcanvas(gl)));
Ivica Bukvic
committed
glob_preset_node_list_seek_hub();
glob_preset_node_list_check_loc_and_update();
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
}
void canvas_floatatom(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
{
canvas_atom(gl, A_FLOAT, s, argc, argv);
}
void canvas_symbolatom(t_glist *gl, t_symbol *s, int argc, t_atom *argv)
{
canvas_atom(gl, A_SYMBOL, s, argc, argv);
}
static void gatom_free(t_gatom *x)
{
if (*x->a_symfrom->s_name)
pd_unbind(&x->a_text.te_pd,
canvas_realizedollar(x->a_glist, x->a_symfrom));
gfxstub_deleteforkey(x);
}
static void gatom_properties(t_gobj *z, t_glist *owner)
{
t_gatom *x = (t_gatom *)z;
//char buf[200];
//sprintf(buf, "pdtk_gatom_dialog %%s %d %g %g %d {%s} {%s} {%s}\n",
// x->a_text.te_width, x->a_draglo, x->a_draghi,
// x->a_wherelabel, gatom_escapit(x->a_label)->s_name,
// gatom_escapit(x->a_symfrom)->s_name,
// gatom_escapit(x->a_symto)->s_name);
//gfxstub_new(&x->a_text.te_pd, x, buf);
gui_start_vmess("gui_gatom_dialog", "s",
gfxstub_new2(&x->a_text.te_pd, x));
gui_start_array();
gui_s("width"); gui_i(x->a_text.te_width);
gui_s("draglo"); gui_f(x->a_draglo);
gui_s("draghi"); gui_f(x->a_draghi);
gui_s("labelpos"); gui_i(x->a_wherelabel);
gui_s("label"); gui_s(gatom_escapit(x->a_label)->s_name);
gui_s("receive-symbol"); gui_s(gatom_escapit(x->a_symfrom)->s_name);
gui_s("send-symbol"); gui_s(gatom_escapit(x->a_symto)->s_name);
}
/* -------------------- widget behavior for text objects ------------ */
/* variant of the glist_findrtext found in g_rtext.c
that does not throw a consistency check */
extern t_rtext *glist_tryfindrtext(t_glist *gl, t_text *who);
static void text_getrect(t_gobj *z, t_glist *glist,
int *xp1, int *yp1, int *xp2, int *yp2)
{
//fprintf(stderr,"text_getrect\n");
int width = 0, height = 0, iscomment = (x->te_type == T_TEXT);
t_float x1, y1, x2, y2;
/* for number boxes, we know width and height a priori, and should
report them here so that graphs can get swelled to fit. */
if (x->te_type == T_ATOM && x->te_width > 0)
{
//fprintf(stderr," T_ATOM\n");
int font = glist_getfont(glist);
int fontwidth = sys_fontwidth(font), fontheight = sys_fontheight(font);
width = (x->te_width > 0 ? x->te_width : 6) * fontwidth + 2;
height = fontheight + 3; /* borrowed from TMARGIN, etc, in g_rtext.c */
// jsarlo
else if (strcmp("magicGlass", class_getname(x->ob_pd)) == 0)
{
width = 0;
height = 0;
}
// end jsarlo
else if (x->te_type == T_TEXT)
{
//fprintf(stderr," T_TEXT\n");
t_rtext *y = glist_findrtext(glist, x);
if (y)
{
width = rtext_width(y);
height = rtext_height(y);
}
else
{
width = height = 10;
}
//fprintf(stderr,"T_TEXT width=%d height=%d\n", width, height);
}
/* if we're invisible we don't know our size so we just lie about
it. This is called on invisible boxes to establish order of inlets
and possibly other reasons.
To find out if the box is visible we can't just check the "vis"
flag because we might be within the vis() routine and not have set
that yet. So we check directly whether the "rtext" list has been
built. LATER reconsider when "vis" flag should be on and off? */
else if (glist->gl_editor && glist->gl_editor->e_rtext)
{
t_rtext *y = glist_tryfindrtext(glist, x);
if (y)
{
width = rtext_width(y);
height = rtext_height(y) - (iscomment << 1);
}
//fprintf(stderr,"rtext width=%d height=%d\n", width, height);
/* now find if we have more inlets or outlets than
what can comfortably fit and adjust accordingly
NB: textless GOPs are unaffected and are treated
as GUI objects
*/
//fprintf(stderr,"isgraph %d\n", ((t_glist *)z)->gl_isgraph);
//if (!((t_glist *)z)->gl_isgraph) {
t_object *ob = pd_checkobject(&x->te_pd);
int no = obj_noutlets(ob);
int ni = obj_ninlets(ob);
Ivica Bukvic
committed
/*
// debug chunk
char *bufdbg;
int bufsizedbg;
if (y) rtext_gettext(y, &bufdbg, &bufsizedbg);
if (!strncmp(bufdbg, "gate", 4) || strlen(bufdbg) == 0)
fprintf(stderr,"text_getrect nlets %d %d <%s>\n", ni, no, ( y ? bufdbg : "null" ));
*/
int m = ( ni > no ? ni : no);
//let's see if the object has more nlets than
//its text width and resize them accordingly
//UNLESS we are gop in which case it is user's choice
//how big/small they want the object
if (pd_class(&z->g_pd) != canvas_class ||
pd_class(&z->g_pd) == canvas_class &&
!((t_glist *)z)->gl_isgraph)
{
if (width < (IOWIDTH * m) * 2 - IOWIDTH)
{
//we have to resize the object
width = (IOWIDTH * m) * 2 - IOWIDTH;
}
}
height = rtext_height(y) - (iscomment << 1);
}
width = height = 10;
//fprintf(stderr," default\n");
}
x1 = text_xpix(x, glist);
y1 = text_ypix(x, glist);
x2 = x1 + width;
y2 = y1 + height;
//x1 += iscomment*2;
*xp1 = x1;
*yp1 = y1;
*xp2 = x2;
*yp2 = y2;
}
static void text_displace(t_gobj *z, t_glist *glist,
int dx, int dy)
{
//fprintf(stderr,"text_displace\n");
t_text *x = (t_text *)z;
x->te_xpix += dx;
x->te_ypix += dy;
if (glist_isvisible(glist))
{
t_rtext *y = glist_findrtext(glist, x);
gui_vmess("gui_text_displace", "xsii",
glist, rtext_gettag(y), dx, dy);
// t_rtext *y = glist_findrtext(glist, x);
// rtext_displace(y, dx, dy);
// text_drawborder(x, glist, rtext_gettag(y),
// rtext_width(y), rtext_height(y), 0);
canvas_fixlinesfor(glist_getcanvas(glist), x);
}
}
static void text_displace_withtag(t_gobj *z, t_glist *glist,
int dx, int dy)
{
//fprintf(stderr,"text_displace_withtag\n");
t_text *x = (t_text *)z;
x->te_xpix += dx;
x->te_ypix += dy;
if (glist_isvisible(glist))
{
Ivica Ico Bukvic
committed
//text_drawborder_withtag(x, glist, rtext_gettag(y),
// rtext_width(y), rtext_height(y), 0);
canvas_fixlinesfor(glist_getcanvas(glist), x);
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
/* if this is a subpatcher in which case we may be
possibly moving nlets around
which in turn requires that we redraw parent's nlets */
/* if (glist->gl_owner && glist_isvisible(glist->gl_owner))
{
int resortin = 0, resortout = 0;
t_class *cl = pd_class(&z->g_pd);
if (cl == vinlet_class) resortin = 1;
else if (cl == voutlet_class) resortout = 1;
fprintf(stderr,"vinlet=%d voutlet=%d\n", resortin, resortout);
if (resortin) canvas_resortinlets(glist->gl_owner);
if (resortout) canvas_resortoutlets(glist->gl_owner);
char *buf;
char name[6];
int bufsize, i;
rtext_gettext(y, &buf, &bufsize);
for (i = 0; i < 5; i++)
{
name[i] = buf[i];
}
name[5] = '\0';
//fprintf(stderr,"yes, this is a subpatch with visible parent %s\n",
// name);
if (!strcmp(name, "inlet") ||
!strcmp(name, "outle"))
{
//fprintf(stderr,"yes, we're moving nlets around\n");
glist_redraw(glist->gl_owner);
}
}*/
}
}
static void gatom_displace_withtag(t_gobj *z, t_glist *glist,
int dx, int dy)
{
text_displace_withtag(z, glist, dx, dy);
Ivica Ico Bukvic
committed
//sys_vgui(".x%lx.c move %lx.l %d %d\n", glist_getcanvas(glist),
// x, dx, dy);
static void text_select(t_gobj *z, t_glist *glist, int state)
{
t_text *x = (t_text *)z;
t_rtext *y = glist_findrtext(glist, x);
//fprintf(stderr,"text_select %s %d\n", rtext_gettag(y), state);
Ivica Bukvic
committed
Ivica Bukvic
committed
// text_class is either a comment or an object that failed to create
Ivica Bukvic
committed
// so we distinguish between it and comment using T_TEXT type check
if (pd_class(&x->te_pd) == text_class && x->te_type != T_TEXT)
outline = "$pd_colors(dash_outline)";
else if (z->g_pd == gatom_class)
outline = "$pd_colors(atom_box_border)";
else
outline = "$pd_colors(box_border)";
//fprintf(stderr,"text_select isvisible=%d shouldvis=%d istoplevel=%d\n",
// glist_isvisible(glist), gobj_shouldvis(&x->te_g, glist),
// glist_istoplevel(glist));
if (gobj_shouldvis(&x->te_g, glist))
{
if (glist_istoplevel(glist))
{
//sys_vgui(".x%lx.c itemconfigure %sR -stroke %s\n",
// glist_getcanvas(glist), rtext_gettag(y),
// (state? "$pd_colors(selection)" : outline));
gui_vmess("gui_text_select_color", "xs",
glist_getcanvas(glist), rtext_gettag(y));
if (z->g_pd == gatom_class)
{
//sys_vgui(".x%lx.c itemconfigure %lx.l -fill %s\n",
// glist_getcanvas(glist), x,
// (state? "$pd_colors(selection)" : "$pd_colors(text)"));
}
}
if (z->g_pd->c_wb && z->g_pd->c_wb->w_displacefnwtag)
{
if (state)
{
if (z->g_pd == gatom_class)
{
/* Since the label is a child of the parent gobj, we
only need to select the gobj to displace it */
//sys_vgui(".x%lx.c addtag selected withtag %lx.l\n",
// glist_getcanvas(glist), x);
//sys_vgui(".x%lx.c addtag selected withtag %sR \n",
// glist_getcanvas(glist), rtext_gettag(y));
gui_vmess("gui_gobj_select", "xs",
glist_getcanvas(glist), rtext_gettag(y));
if (pd_class(&x->te_pd) == text_class &&
x->te_type != T_TEXT &&
glist_istoplevel(glist))
{
/* Not sure yet what this is doing... */
sys_vgui(".x%lx.c itemconfigure %sR -strokewidth 1 "
"-strokedasharray {} "
"-fill $pd_colors(box)\n",
glist_getcanvas(glist), rtext_gettag(y));
t_object *ob = pd_checkobject(&x->te_pd);
int no = obj_noutlets(ob);
int ni = obj_ninlets(ob);
for (i = 0; i < no; i++)
{
/* Not necessary since xlet rect is child of gobj */
//sys_vgui(".x%lx.c addtag selected withtag %so%d \n",
// glist_getcanvas(glist), rtext_gettag(y), i);
}
for (i = 0; i < ni; i++)
{
/* Not necessary since xlet rect is child of gobj */
//sys_vgui(".x%lx.c addtag selected withtag %si%d \n",
// glist_getcanvas(glist), rtext_gettag(y), i);
}
}
else
{
if (z->g_pd == gatom_class)
{
//sys_vgui(".x%lx.c dtag %lx.l selected\n",
// glist_getcanvas(glist), x);
//sys_vgui(".x%lx.c dtag %sR selected\n",
// glist_getcanvas(glist), rtext_gettag(y));
gui_vmess("gui_gobj_deselect", "xs",
glist_getcanvas(glist),
if (pd_class(&x->te_pd) == text_class &&
x->te_type != T_TEXT)
{
/* This might be for broken objects... */
sys_vgui(".x%lx.c itemconfigure %sR -strokewidth 2 "
"-strokelinecap projecting -strokedasharray {2 3} "
"-fill %s\n",
glist_getcanvas(glist),
rtext_gettag(y), invalid_fill);
t_object *ob = pd_checkobject(&x->te_pd);
int no = obj_noutlets(ob);
int ni = obj_ninlets(ob);
for (i = 0; i < no; i++)
{
//sys_vgui(".x%lx.c dtag %so%d selected\n",
// glist_getcanvas(glist), rtext_gettag(y), i);
}
for (i = 0; i < ni; i++)
{
//sys_vgui(".x%lx.c dtag %si%d selected\n",
// glist_getcanvas(glist), rtext_gettag(y), i);
}
}
}
}
}
static void text_activate(t_gobj *z, t_glist *glist, int state)
{
t_text *x = (t_text *)z;
t_rtext *y = glist_findrtext(glist, x);
if (z->g_pd != gatom_class) rtext_activate(y, state);
}
static void text_delete(t_gobj *z, t_glist *glist)
{
t_text *x = (t_text *)z;
canvas_deletelinesfor(glist, x);
}
Jonathan Wilkes
committed
static void text_get_typestring(int type, char *buf)
{
if (type == T_OBJECT)
sprintf(buf, "%s", "obj");
else if (type == T_MESSAGE)
sprintf(buf, "%s", "msg");
else if (type == T_TEXT)
sprintf(buf, "%s", "comment");
else
sprintf(buf, "%s", "atom");
}
static void text_vis(t_gobj *z, t_glist *glist, int vis)
{
//fprintf(stderr,"text_vis %d\n", vis);
Jonathan Wilkes
committed
char type[8];
text_get_typestring(x->te_type, type);
Ivica Bukvic
committed
#ifdef PDL2ORK
//if we are in k12 mode and this is hub with level 1 (global)
//don't draw it and make its width/height 0
int exception = 0;
if (pd_class(&x->te_pd) == preset_hub_class && sys_k12_mode)
{
//fprintf(stderr,"text_vis reports preset_hub_class detected\n");
t_preset_hub *h = (t_preset_hub *)z;
if (h->ph_invis)
{
exception = 1;
x->te_width = 0;
}
}
if (!exception)
{
Ivica Bukvic
committed
#endif
if (vis)
{
if (gobj_shouldvis(&x->te_g, glist))
{
//fprintf(stderr," draw it\n");
t_rtext *y = glist_findrtext(glist, x);
// make a group
text_getrect(&x->te_g, glist, &x1, &y1, &x2, &y2);
gui_vmess("gui_text_create_gobj", "xssiii",
glist_getcanvas(glist),
Jonathan Wilkes
committed
rtext_gettag(y), type, x1, y1, glist_istoplevel(glist));
if (x->te_type == T_ATOM)
glist_retext(glist, x);
text_drawborder(x, glist, rtext_gettag(y),
rtext_width(y), rtext_height(y), 1);
rtext_draw(y);
}
}
else
{
t_rtext *y = glist_findrtext(glist, x);
if (gobj_shouldvis(&x->te_g, glist))
{
Ivica Bukvic
committed
//fprintf(stderr," erase it %lx %lx\n", x, glist);
text_erase_gobj(x, glist, rtext_gettag(y));
//text_eraseborder(x, glist, rtext_gettag(y));
//rtext_erase(y);
}
}
Ivica Bukvic
committed
#ifdef PDL2ORK
Ivica Bukvic
committed
#endif
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
}
static int text_click(t_gobj *z, struct _glist *glist,
int xpix, int ypix, int shift, int alt, int dbl, int doit)
{
t_text *x = (t_text *)z;
if (x->te_type == T_OBJECT)
{
t_symbol *clicksym = gensym("click");
if (zgetfn(&x->te_pd, clicksym))
{
if (doit)
pd_vmess(&x->te_pd, clicksym, "fffff",
(double)xpix, (double)ypix,
(double)shift, (double)0, (double)alt);
return (1);
}
else return (0);
}
else if (x->te_type == T_ATOM)
{
t_canvas *canvas = glist_getcanvas(glist);
t_rtext *y = glist_findrtext(glist, x);
if (doit)
{
//fprintf(stderr,"atom click\n");
/* Change the gatom blue when it's clicked? Need to test... */
sys_vgui(".x%lx.c itemconfigure %s -fill %s\n", canvas,
rtext_gettag(y), "$pd_colors(selection)");
Ivica Bukvic
committed
gatom_click((t_gatom *)x, (t_floatarg)xpix, (t_floatarg)ypix,
(t_floatarg)shift, (t_floatarg)0, (t_floatarg)alt);
return (1);
}
else if (x->te_type == T_MESSAGE)
{
if (doit)
message_click((t_message *)x, (t_floatarg)xpix, (t_floatarg)ypix,
(t_floatarg)shift, (t_floatarg)0, (t_floatarg)alt);
return (1);
}
else return (0);
}
void text_save(t_gobj *z, t_binbuf *b)
{
//fprintf(stderr, "text_save\n");
t_text *x = (t_text *)z;
if (x->te_type == T_OBJECT)
{
/* if we have a "saveto" method, and if we don't happen to be
a canvas that's an abstraction, the saveto method does the work */
if (zgetfn(&x->te_pd, gensym("saveto")) &&
!((pd_class(&x->te_pd) == canvas_class) &&
(canvas_isabstraction((t_canvas *)x)
|| canvas_istable((t_canvas *)x))))
{
//fprintf(stderr, "saveto\n");
mess1(&x->te_pd, gensym("saveto"), b);
binbuf_addv(b, "ssii", gensym("#X"), gensym("restore"),
(int)x->te_xpix, (int)x->te_ypix);
}
else /* otherwise just save the text */
{
//fprintf(stderr, "is this gop?\n");
binbuf_addv(b, "ssii", gensym("#X"), gensym("obj"),
(int)x->te_xpix, (int)x->te_ypix);
}
//fprintf(stderr, "this must be it\n");
//fprintf(stderr, "DONE this must be it\n");
}
else if (x->te_type == T_MESSAGE)
{
//fprintf(stderr, "message\n");
binbuf_addv(b, "ssii", gensym("#X"), gensym("msg"),
(int)x->te_xpix, (int)x->te_ypix);
binbuf_addbinbuf(b, x->te_binbuf);
}
else if (x->te_type == T_ATOM)
{
//fprintf(stderr, "atom\n");
t_atomtype t = ((t_gatom *)x)->a_atom.a_type;
t_symbol *sel = (t == A_SYMBOL ? gensym("symbolatom") :
(t == A_FLOAT ? gensym("floatatom") : gensym("intatom")));
t_symbol *label = gatom_escapit(((t_gatom *)x)->a_label);
t_symbol *symfrom = gatom_escapit(((t_gatom *)x)->a_symfrom);
t_symbol *symto = gatom_escapit(((t_gatom *)x)->a_symto);
binbuf_addv(b, "ssiiifffsss", gensym("#X"), sel,
(int)x->te_xpix, (int)x->te_ypix, (int)x->te_width,
(double)((t_gatom *)x)->a_draglo,
(double)((t_gatom *)x)->a_draghi,
(double)((t_gatom *)x)->a_wherelabel,
label, symfrom, symto);
}
Ivica Bukvic
committed
else
Ivica Bukvic
committed
//fprintf(stderr,"comment\n");
int natom = binbuf_getnatom(x->te_binbuf);
t_atom *a = binbuf_getvec(x->te_binbuf);
int i;
for (i = 0; i < natom; i++)
{
Ivica Bukvic
committed
t_symbol *s;
if(a[i].a_type == A_SYMBOL)
{
Ivica Bukvic
committed
//fprintf(stderr,"%d is a symbol\n", i);
s = a[i].a_w.w_symbol;
if (s != NULL && s->s_name != NULL)
{
Ivica Bukvic
committed
//fprintf(stderr,"s != NULL\n");
char *c;
for(c = s->s_name; c != NULL && *c != '\0'; c++)
{
if(*c == '\n')
{
Ivica Bukvic
committed
*c = '\v';
//fprintf(stderr,"n->v\n");
}
}
}
}
}
binbuf_addv(b, "ssii", gensym("#X"), gensym("text"),
(int)x->te_xpix, (int)x->te_ypix);
binbuf_addbinbuf(b, x->te_binbuf);
Ivica Bukvic
committed
}
Ivica Bukvic
committed
if (x->te_width)
binbuf_addv(b, ",si", gensym("f"), (int)x->te_width);
binbuf_addv(b, ";");
}
/* this one is for everyone but "gatoms"; it's imposed in m_class.c */
t_widgetbehavior text_widgetbehavior =
{
text_getrect,
text_displace,
text_select,
text_activate,
text_delete,
text_vis,
text_click,
};
static t_widgetbehavior gatom_widgetbehavior =
{
text_getrect,
gatom_displace,
text_select,
text_activate,
text_delete,
gatom_vis,
text_click,
};
/* -------------------- the "text" class ------------ */
#define EXTRAPIX 2
/* draw inlets and outlets for a text object or for a graph. */
void glist_drawiofor(t_glist *glist, t_object *ob, int firsttime,
char *tag, int x1, int y1, int x2, int y2)
{
//if this is a comment or we are drawing inside gop on one of
//our parents return
if (pd_class(&ob->te_pd) == text_class || glist_getcanvas(glist) != glist)
return;
//fprintf(stderr,"glist_drawiofor\n");
int n = obj_noutlets(ob), nplus = (n == 1 ? 1 : n-1), i;
int width = x2 - x1;
int selected = glist_isselected(glist, (t_gobj*)ob);
for (i = 0; i < n; i++)
{
int onset = x1 + (width - IOWIDTH) * i / nplus;
if (firsttime)
//fprintf(stderr,"glist_drawiofor o firsttime\n");
//sys_vgui(".x%lx.c create prect %d %d %d %d \
// -fill %s -stroke %s -tags {%so%d %lx outlet %s %s}\n",
// glist_getcanvas(glist), onset, y2 - 2, onset + IOWIDTH, y2,
// (issignal ? "$pd_colors(signal_nlet)" :
// "$pd_colors(control_nlet)"),
// (issignal ? "$pd_colors(signal_cord)" :
// "$pd_colors(control_cord)"),
// tag, i, tag,
// (issignal ? "signal" : "control"),
// (selected ? "selected" : ""));
/* need to send issignal and is_iemgui here... */
gui_vmess("gui_canvas_drawio", "xssiiiiiisiii",
glist_getcanvas(glist), rtext_gettag(y), tag,
onset, y2 - 2, onset + IOWIDTH, y2, x1, y1, "o", i,
issignal, 0);
//fprintf(stderr,"glist_drawiofor o redraw\n");
Jonathan Wilkes
committed
//sys_vgui(".x%lx.c coords %so%d %d %d %d %d\n",
// glist_getcanvas(glist), tag, i,
// onset, y2 - 2,
// onset + IOWIDTH, y2);
// jsarlo
/*sys_vgui(".x%x.c raise %so%d\n",
glist_getcanvas(glist),
tag,
i);*/
// end jsarlo
Jonathan Wilkes
committed
gui_vmess("gui_canvas_redraw_io", "xssiisiii",
glist_getcanvas(glist), rtext_gettag(y), tag,
}
n = obj_ninlets(ob);
nplus = (n == 1 ? 1 : n-1);
for (i = 0; i < n; i++)
{
int onset = x1 + (width - IOWIDTH) * i / nplus;
if (firsttime)
//fprintf(stderr,"glist_drawiofor i firsttime\n");
//sys_vgui(".x%lx.c create prect %d %d %d %d \
// -fill %s -stroke %s -tags {%si%d %lx inlet %s %s}\n",
// glist_getcanvas(glist), onset, y1,
// onset + IOWIDTH, y1 + EXTRAPIX,
// (issignal ? "$pd_colors(signal_nlet)" :
// "$pd_colors(control_nlet)"),
// (issignal ? "$pd_colors(signal_cord)" :
// "$pd_colors(control_cord)"),
// tag, i, tag,
// (issignal ? "signal" : "control"),
// (selected ? "selected" : ""));
gui_vmess("gui_canvas_drawio", "xssiiiiiisiii",
glist_getcanvas(glist), rtext_gettag(y), tag,
onset, y1, onset + IOWIDTH, y1 + EXTRAPIX, x1, y1, "i", i,
issignal, 0);
//fprintf(stderr,"glist_drawiofor i firsttime\n");
Jonathan Wilkes
committed
//sys_vgui(".x%lx.c coords %si%d %d %d %d %d\n",
// glist_getcanvas(glist), tag, i,
// onset, y1,
// onset + IOWIDTH, y1 + EXTRAPIX);
// jsarlo
/*sys_vgui(".x%x.c raise %si%d\n",
glist_getcanvas(glist),
tag,
i);*/
// end jsarlo
Jonathan Wilkes
committed
gui_vmess("gui_canvas_redraw_io", "xssiisiii",
glist_getcanvas(glist), rtext_gettag(y), tag,
/* draw inlets and outlets for a text object or for a graph. */
void glist_drawiofor_withtag(t_glist *glist, t_object *ob, int firsttime,
char *tag, int x1, int y1, int x2, int y2)
{
if (pd_class(&ob->te_pd) == text_class)
return;
//fprintf(stderr,"drawiofor_withtag\n");
int n = obj_noutlets(ob), nplus = (n == 1 ? 1 : n-1), i;
int width = x2 - x1;
int issignal;
for (i = 0; i < n; i++)
{
int onset = x1 + (width - IOWIDTH) * i / nplus;
if (firsttime)
{
//fprintf(stderr,"drawiofor_withtag o firsttime\n");
issignal = obj_issignaloutlet(ob,i);
/* Hm, I can't seem to find a case where this is needed
yet. All the xlets in nw.js port load and get created
correctly without it... */
Ivica Bukvic
committed
sys_vgui(".x%lx.c create prect %d %d %d %d \
-fill %s -stroke %s -tags {%so%d %lx outlet}\n",
glist_getcanvas(glist), onset, y2 - 2, onset + IOWIDTH, y2,
(issignal ? "$pd_colors(signal_nlet)" :
"$pd_colors(control_nlet)"),
(issignal ? "$pd_colors(signal_cord)" :
"$pd_colors(control_cord)"),
Ivica Bukvic
committed
tag, i, tag);
else
{
sys_vgui(".x%lx.c addtag selected withtag %so%d \n",
glist_getcanvas(glist), tag, i);
}
*/
}
n = obj_ninlets(ob);
//fprintf(stderr,"drawiofor_withtag n=%d\n", n);
nplus = (n == 1 ? 1 : n-1);
for (i = 0; i < n; i++)
{
int onset = x1 + (width - IOWIDTH) * i / nplus;
if (firsttime)
{
//fprintf(stderr,"drawiofor_withtag i firsttime\n");
issignal = obj_issignalinlet(ob,i);
Ivica Bukvic
committed
sys_vgui(".x%lx.c create prect %d %d %d %d \
-fill %s -stroke %s -tags {%si%d %lx inlet}\n",
glist_getcanvas(glist), onset, y1,
onset + IOWIDTH, y1 + EXTRAPIX,
(issignal ? "$pd_colors(signal_nlet)" :
"$pd_colors(control_nlet)"),
(issignal ? "$pd_colors(signal_cord)" :
"$pd_colors(control_cord)"),
Ivica Bukvic
committed
tag, i, tag);
/* else
{
//sys_vgui(".x%lx.c addtag selected withtag %si%d \n",
// glist_getcanvas(glist), tag, i);
fprintf(stderr,"drawiofor_withtag i redraw\n");
issignal = obj_issignalinlet(ob,i);
sys_vgui(".x%lx.c itemconfigure %si%d \
-fill %s -outline %s\n",
glist_getcanvas(glist), tag, i,
(issignal ? "$pd_colors(signal_nlet)" :
"$pd_colors(control_nlet)"),
(issignal ? "$pd_colors(signal_cord)" :
"$pd_colors(control_cord)"));
}
*/
}
}
void text_drawborder(t_text *x, t_glist *glist,
char *tag, int width2, int height2, int firsttime)
{
Ivica Bukvic
committed
//fprintf(stderr,"text_drawborder\n");
int selected = glist_isselected(glist, (t_gobj*)x);
/* if this is gop patcher, the getrect should be equal to gop-ed window
rather than just the size of text */
if (pd_class(&x->te_pd) == canvas_class &&
((t_glist *)x)->gl_isgraph &&
((t_glist *)x)->gl_goprect &&
!(((t_glist *)x)->gl_havewindow) )
{
int gop_width = ((t_glist *)x)->gl_pixwidth;
int gop_height = ((t_glist *)x)->gl_pixheight;
text_getrect(&x->te_g, glist, &x1, &y1, &x2, &y2);
/*fprintf(stderr,"text = %d %d %d %d gop = %d %d\n",
x1, y1, x2, y2, gop_width, gop_height); */
if (gop_width > (x2-x1)) x2 = x1 + gop_width;
if (gop_height > (y2-y1)) y2 = y1 + gop_height;
}
else
{
text_getrect(&x->te_g, glist, &x1, &y1, &x2, &y2);
}
char *pattern; char *outline; char *fill;
/* tag to identify broken boxes from tcl/tk */
char *box_tag;
if (pd_class(&x->te_pd) == text_class)
{
pattern = "-";
Ivica Bukvic
committed
outline = "$pd_colors(dash_outline) -strokewidth 2 -strokelinecap projecting -strokedasharray {2 3}"; //-strokedasharray {4 1}
fill = invalid_fill;
box_tag = "broken box";
outline = "$pd_colors(box_border)";
Ivica Bukvic
committed
fill = "$pd_colors(box)";
box_tag = "box";
Ivica Bukvic
committed
sys_vgui(".x%lx.c create ppolygon %d %d %d %d %d %d %d %d %d %d \
-stroke %s -fill %s -tags {%sR %lx text %s %s}\n",
glist_getcanvas(glist),
x1, y1, x2, y1, x2, y2, x1, y2, x1, y1,
(selected ? "$pd_colors(selection)" : outline),
fill, tag, tag, box_tag,
(selected ? "selected" : ""));
gui_vmess("gui_text_drawborder", "xssiiiii",
glist_getcanvas(glist), tag, "none",
Jonathan Wilkes
committed
broken, x1, y1, x2, y2);
Loading
Loading full blame...