Skip to content
Snippets Groups Projects
g_text.c 92 KiB
Newer Older
                /*sys_vgui(".x%x.c raise %so%d\n",
                         glist_getcanvas(glist),
                         tag,
                         i);*/
                // end jsarlo
            gui_vmess("gui_canvas_redraw_io", "xssiisiii",
                glist_getcanvas(glist), rtext_gettag(y), tag,
                onset, y2 - 2, "o", i, x1, y1);
Miller Puckette's avatar
Miller Puckette committed
    }
    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");
            issignal = obj_issignalinlet(ob,i);
            //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");
            //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
            gui_vmess("gui_canvas_redraw_io", "xssiisiii",
                glist_getcanvas(glist), rtext_gettag(y), tag,
                onset, y1, "i", i, x1, y1);
    /* 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... */
            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)"),
        else
        {
            sys_vgui(".x%lx.c addtag selected withtag %so%d \n",
                glist_getcanvas(glist), tag, i);
        }
    //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);
            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)"),
/*        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)"));
        }
Miller Puckette's avatar
Miller Puckette committed
void text_drawborder(t_text *x, t_glist *glist,
    char *tag, int width2, int height2, int firsttime)
{
Miller Puckette's avatar
Miller Puckette committed
    t_object *ob;
Mathieu L Bouchard's avatar
Mathieu L Bouchard committed
    int x1, y1, x2, y2;
    int broken;
    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);
    }
Miller Puckette's avatar
Miller Puckette committed
    if (x->te_type == T_OBJECT)
    {
        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 = "-";
            outline = "$pd_colors(dash_outline) -strokewidth 2 -strokelinecap projecting -strokedasharray {2 3}"; //-strokedasharray {4 1}
            fill = invalid_fill;
            box_tag = "broken box";
            broken = 1;
        }
        else
        {
            pattern = "\"\"";
            outline = "$pd_colors(box_border)";
            broken = 0;
Miller Puckette's avatar
Miller Puckette committed
        if (firsttime)
            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",
                //-dash %s -> pattern disabled for tkpath
            //fprintf(stderr, "redrawing rectangle? .x%lx.c %sR\n",
            //    (t_int)glist_getcanvas(glist), tag);
            //sys_vgui(".x%lx.c coords %sR %d %d %d %d %d %d %d %d %d %d\n",
            //    glist_getcanvas(glist), tag,
            //        x1, y1,  x2, y1,  x2, y2,  x1, y2,  x1, y1);
            gui_vmess("gui_text_redraw_border", "xsiiii",
                glist_getcanvas(glist), tag, x1, y1, x2, y2);
/* this seems to be totally extraneous  hans@at.or.at
             sys_vgui(".x%lx.c itemconfigure %sR -dash %s -outline %s\n", 
                     glist_getcanvas(glist), tag, pattern, outline); */
Miller Puckette's avatar
Miller Puckette committed
        }
    }
    else if (x->te_type == T_MESSAGE)
    {
        if (firsttime)
            sys_vgui(".x%lx.c create ppolygon "
                     "%d %d %d %d %d %d %d %d %d %d %d %d %d %d "
                     "-stroke %s -fill $pd_colors(msg) "
                     "-tags {%sR %lx text msg box %s}\n",
Miller Puckette's avatar
Miller Puckette committed
                glist_getcanvas(glist),
                x1, y1,  x2+4, y1,  x2, y1+4,  x2, y2-4,  x2+4, y2,
Miller Puckette's avatar
Miller Puckette committed
                x1, y2,  x1, y1,
                (selected ? "$pd_colors(selection)" : "$pd_colors(msg_border)"),
                    tag, tag, (selected ? "selected" : ""));
            */

            // coords are a quick hack to separate gobj's x/y from the polygon's coords
            // which of course can be greatly simplified
            gui_vmess("gui_message_drawborder", "xsii",
                glist_getcanvas(glist), tag, x2 - x1, y2 - y1);
//                x1-x1, y1-y1, x2+4-x1, y1-y1, x2-x1,
//                y1+4-y1, x2-x1, y2-4-y1, x2+4-x1, y2-y1, x1-x1, y2-y1, x1-x1, y1-y1);
        }
Miller Puckette's avatar
Miller Puckette committed
        else
            //sys_vgui(".x%lx.c coords %sR "
            //         "%d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
            //    glist_getcanvas(glist), tag,
            //    x1, y1,  x2+4, y1,  x2, y1+4,  x2, y2-4,  x2+4, y2,
            //    x1, y2,  x1, y1);
            gui_vmess("gui_message_redraw_border", "xsiiiiiiiiiiiiii",
                glist_getcanvas(glist), tag,
                x1-x1, y1-y1,  x2+4-x1, y1-y1,  x2-x1, y1+4-y1, x2-x1, y2-4-y1,  x2+4-x1, y2-y1,
                x1-x1, y2-y1,  x1-x1, y1-y1);
        }
Miller Puckette's avatar
Miller Puckette committed
    }
    else if (x->te_type == T_ATOM)
    {
        if (firsttime)
            //sys_vgui(".x%lx.c create ppolygon "
            //         "%d %d %d %d %d %d %d %d %d %d %d %d "
            //         "-stroke %s "
            //         "-fill $pd_colors(atom_box) "
            //         "-tags {%sR %lx text atom box %s}\n",
            //    glist_getcanvas(glist),
            //    x1, y1,  x2-4, y1,  x2, y1+4,  x2, y2,  x1, y2,  x1, y1,
            //    (selected ? "$pd_colors(selection)" : "$pd_colors(atom_box_border)"),
            //        tag, tag, (selected ? "selected" : ""));
            gui_vmess("gui_atom_drawborder", "xsiiiiiiiiiiii",
                glist_getcanvas(glist), tag,
                x1-x1, y1-y1, x2-4-x1, y1-y1, x2-x1,
                y1+4-y1, x2-x1, y2-y1, x1-x1, y2-y1, x1-x1, y1-y1);
        }
            sys_vgui(".x%lx.c coords %sR "
                     "%d %d %d %d %d %d %d %d %d %d %d %d\n",
Miller Puckette's avatar
Miller Puckette committed
                glist_getcanvas(glist), tag,
                x1, y1,  x2-4, y1,  x2, y1+4,  x2, y2,  x1, y2,  x1, y1);
        /* for comments, just draw a dotted rectangle unlocked; when a visible
        canvas is unlocked we have to call this anew on all comments, and when
        locked we erase them all via the annoying "commentbar" tag. IB: However
        we do not draw these unless the comments in question are being drawn
        on top level--this avoids bugggy behavior where comment rectangles are
        drawn inside a GOP on another toplevel glist when the GOP subpatch is
        in edit mode */
    else if (x->te_type == T_TEXT && glist->gl_edit && glist_istoplevel(glist))
            /*sys_vgui(".x%lx.c create pline\
                 %d %d %d %d -tags [list %sR commentbar] -stroke $pd_colors(atom_box_border)\n",*/
            sys_vgui(".x%lx.c create ppolygon %d %d %d %d %d %d %d %d %d %d\
                -tags [list %sR commentbar %s] -stroke %s\
                -strokewidth 1 -strokedasharray {2 2} -strokelinecap butt\n",
                x1, y1,  x2, y1,  x2, y2,  x1, y2,  x1, y1, tag,
                (selected ? "selected" : ""),
                (selected ? "$pd_colors(selection)" : "$pd_colors(box_border)"));
            /* Not needed... only the parent gobj group needs to be displaced */
            //sys_vgui(".x%lx.c coords %sR %d %d %d %d %d %d %d %d %d %d\n",
            //    glist_getcanvas(glist), tag, x1, y1,  x2, y1,  x2, y2,  x1, y2,  x1, y1);
    /* draw inlets/outlets */    
    if (ob = pd_checkobject(&x->te_pd))
    {
        glist_drawiofor(glist, ob, firsttime, tag, x1, y1, x2, y2);
    }
    /* raise cords over everything else */
    if (firsttime && glist==glist_getcanvas(glist))
    //ico@bukvic.net 100518 update scrollbars when GOP
    //potentially exceeds window size
    //    (long unsigned int)glist_getcanvas(glist));
}

void text_drawborder_withtag(t_text *x, t_glist *glist,
    char *tag, int width2, int height2, int firsttime)
{
    t_object *ob;
Mathieu L Bouchard's avatar
Mathieu L Bouchard committed
    int x1, y1, x2, y2, msg_draw_const, atom_draw_const;
    text_getrect(&x->te_g, glist, &x1, &y1, &x2, &y2);
    if (x->te_type == T_OBJECT)
    {
        char *pattern; char *outline; char *fill;
        if (pd_class(&x->te_pd) == text_class)
        {
            pattern = "-";
            outline = "$pd_colors(dash_outline) -strokewidth 2 -strokelinecap projecting -strokedasharray {2 3}";
            outline = "$pd_colors(box_border)";
            /* Can't figure out if this is needed... */
            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}\n", 
                glist_getcanvas(glist),
                     x1, y1,  x2, y1,  x2, y2,  x1, y2,  x1, y1,  
                //-dash %s -> pattern disabled for tkpath
        }
    }
    else if (x->te_type == T_MESSAGE)
    {
        msg_draw_const = ((y2-y1)/4);
        if (msg_draw_const > 10) msg_draw_const = 10; /* looks bad if too big */
        if (firsttime)
            /* Can't figure out if this is needed... */
            sys_vgui(".x%lx.c create ppolygon "
                     "%d %d %d %d %d %d %d %d %d %d %d %d %d %d "
                     "-stroke $pd_colors(msg_border) -fill $pd_colors(msg) "
                     "-tags {%sR %lx text msg box}\n",
                glist_getcanvas(glist),
                     x1, y1,  x2+msg_draw_const, y1,  x2, y1+msg_draw_const,  
                     x2, y2-msg_draw_const,  x2+msg_draw_const, y2,  
                x1, y2,  x1, y1,
    }
    else if (x->te_type == T_ATOM)
    {
        atom_draw_const = ((y2-y1)/3);
        if (firsttime)
            /* Can't figure out where this is needed */
            sys_vgui(".x%lx.c create ppolygon "
                     "%d %d %d %d %d %d %d %d %d %d %d %d "
                     "-stroke $pd_colors(atom_box_border) "
                     "-fill $pd_colors(atom_box) "
                     "-tags {%sR %lx text atom box}\n",
                glist_getcanvas(glist),
                     x1, y1,  x2-atom_draw_const, y1,  x2, y1+atom_draw_const,  
                     x2, y2,  x1, y2,  x1, y1, 
        /* for comments, draw a dotted box; when a visible
        canvas is unlocked we have to call this anew on all comments, and when
        locked we erase them all via the annoying "commentbar" tag. */
    else if (x->te_type == T_TEXT && glist->gl_edit)
    {
        if (firsttime)
        {
            sys_vgui(".x%lx.c create pline %d %d %d %d "
                     "-tags [list %sR commentbar] -stroke $box_outline\n",
            sys_vgui(".x%lx.c coords %sR %d %d %d %d\n",
                glist_getcanvas(glist), tag, x2, y1,  x2, y2);
        }
Miller Puckette's avatar
Miller Puckette committed
    }
        /* draw inlets/outlets */
    
    if (ob = pd_checkobject(&x->te_pd))
    {
        glist_drawiofor_withtag(glist, ob, firsttime, tag, x1, y1, x2, y2);
    }
    /* raise cords over everything else */
    if (firsttime && glist==glist_getcanvas(glist))
    //ico@bukvic.net 100518 update scrollbars when GOP
    //potentially exceeds window size
    //    (long unsigned int)glist_getcanvas(glist));
Miller Puckette's avatar
Miller Puckette committed
void glist_eraseiofor(t_glist *glist, t_object *ob, char *tag)
{
    //fprintf(stderr,"glist_eraseiofor\n");
    /* This whole function seems unnecessary now... xlets
       get erased with the parent gobj group */
Miller Puckette's avatar
Miller Puckette committed
    int i, n;
    n = obj_noutlets(ob);
    for (i = 0; i < n; i++)
    {
        //sys_vgui(".x%lx.c delete %so%d\n",
        //    glist_getcanvas(glist), tag, i);
    }
Miller Puckette's avatar
Miller Puckette committed
    n = obj_ninlets(ob);
    for (i = 0; i < n; i++)
    {
        //sys_vgui(".x%lx.c delete %si%d\n",
        //    glist_getcanvas(glist), tag, i);
    }
// erase the whole gobj in the gui one go
void text_erase_gobj(t_text *x, t_glist *glist, char *tag)
{
    if (x->te_type == T_TEXT && !glist->gl_edit) return;
    gui_vmess("gui_gobj_erase", "xs", glist_getcanvas(glist), tag);
/* Another function that's unnecessary... parent gobj group will
   erase this for us */
Miller Puckette's avatar
Miller Puckette committed
void text_eraseborder(t_text *x, t_glist *glist, char *tag)
{
    if (x->te_type == T_TEXT && !glist->gl_edit) return;
    //if (!glist_isvisible(glist)) return;
    //sys_vgui(".x%lx.c delete %sR\n",
    //    glist_getcanvas(glist), tag);
Miller Puckette's avatar
Miller Puckette committed
    glist_eraseiofor(glist, x, tag);
}

static int compare_subpatch_selectors(t_atom *a, t_atom *b)
{
    if (a[0].a_type == A_SYMBOL && b[0].a_type == A_SYMBOL)
    {
        return (!strcmp(a[0].a_w.w_symbol->s_name, "pd") &&
                !strcmp(b[0].a_w.w_symbol->s_name, "pd"))
               ||
               (!strcmp(a[0].a_w.w_symbol->s_name, "draw") &&
                !strcmp(b[0].a_w.w_symbol->s_name, "draw"));
void text_checkvalidwidth(t_glist *glist)
{
    // readjust border in case the new object is invalid and it has more connections
    // than what the default width allows (this typically happens when there is a valid
    // object that has been replaced by an invalid one and during recreation the new
    // object has 0 inlets and outlets and is therefore unaware of its possibly greater
    // width)
    t_gobj *yg = glist->gl_list;
    if (yg)
    {
        while (yg->g_next)
            yg = yg->g_next;
        t_text *newest_t = (t_text *)yg;
        //fprintf(stderr, "newest object text class is %lx\n", newest_t);
        t_rtext *yn = glist_findrtext(glist, newest_t);
        if (yn && pd_class(&newest_t->te_pd) == text_class && newest_t->te_type != T_TEXT)
            text_drawborder(newest_t, glist, rtext_gettag(yn), rtext_width(yn), rtext_height(yn), 0);
    }
    /* change text; if T_OBJECT, remake it. */
void text_setto(t_text *x, t_glist *glist, char *buf, int bufsize, int pos)
    //fprintf(stderr,"text_setto %d\n", x->te_type);
Miller Puckette's avatar
Miller Puckette committed
    if (x->te_type == T_OBJECT)
    {
Miller Puckette's avatar
Miller Puckette committed
        t_binbuf *b = binbuf_new();
        int natom1, natom2, widthwas = x->te_width;
Miller Puckette's avatar
Miller Puckette committed
        t_atom *vec1, *vec2;
        binbuf_text(b, buf, bufsize);
        natom1 = binbuf_getnatom(x->te_binbuf);
        vec1 = binbuf_getvec(x->te_binbuf);
        natom2 = binbuf_getnatom(b);
        vec2 = binbuf_getvec(b);
        /* special case: if pd subpatch is valid and its args change,
           and its new name is valid, just pass the message on. */
        if (x->te_pd == canvas_class && natom1 >= 1 && natom2 >= 1 &&
            compare_subpatch_selectors(vec1, vec2))
            //fprintf(stderr,"setto canvas\n");
            //first check if the contents have changed to see if there is
            //any point of recreating the object
            binbuf_gettext(x->te_binbuf, &c1, &i1);
            binbuf_gettext(b, &c2, &i2);
            if (strcmp(c1, c2))
            {
                //fprintf(stderr,"string differs\n");
                canvas_undo_add(glist_getcanvas(glist), 10, "recreate",
                    (void *)canvas_undo_set_recreate(glist_getcanvas(glist),
                    &x->te_g, pos));
                typedmess(&x->te_pd, gensym("rename"), natom2-1, vec2+1);
                binbuf_free(x->te_binbuf);
                x->te_binbuf = b;
                glob_preset_node_list_seek_hub();
                glob_preset_node_list_check_loc_and_update();
                //canvas_apply_restore_original_position(glist_getcanvas(glist),
                //    pos);
            }
            else
            {
                //just retext it
                t_rtext *yr = glist_findrtext(glist, x);
                if (yr) rtext_retext(yr);
Miller Puckette's avatar
Miller Puckette committed
        }
        else  /* normally, just destroy the old one and make a new one. */
        {
            //first check if the contents have changed to see if there
            //is any point of recreating the object
            //fprintf(stderr,"setto not canvas\n");
            binbuf_gettext(x->te_binbuf, &c1, &i1);
            binbuf_gettext(b, &c2, &i2);
            //if the string doesn't match or if the object we entered is invalid
            //(e.g. we created an object that failed to create but now we have an
            //abstraction in patch's path named the same as the desired object)
            if (strcmp(c1, c2) || (pd_class(&x->te_pd) == text_class && x->te_type != T_TEXT))
                //fprintf(stderr,"text_setto calls canvas_undo_add recreate\n");
                canvas_undo_add(glist_getcanvas(glist), 10, "recreate",
                    (void *)canvas_undo_set_recreate(glist_getcanvas(glist),
                    &x->te_g, pos));
                int xwas = x->te_xpix, ywas = x->te_ypix;
                canvas_eraselinesfor(glist, x);
                glist_delete(glist, &x->te_g);
                canvas_objtext(glist, xwas, ywas, widthwas, 0, b);
                    /* if it's an abstraction loadbang it here */
                if (newest && pd_class(newest) == canvas_class)
                    canvas_loadbang((t_canvas *)newest);
                canvas_restoreconnections(glist_getcanvas(glist));
                //canvas_apply_restore_original_position(glist_getcanvas(glist),
                //    pos);
                /* this conditional is here because I'm creating scalars
                   inside of object boxes using canvas_objtext.  But scalars
                   aren't technically t_text, and checkvalidwidth expects
                   to find a new t_text at the end of the glist.
                 */
                if (!scalar_in_a_box)
                    text_checkvalidwidth(glist);
            }
            else
            {
                //fprintf(stderr,"just retext it\n");
                t_rtext *yr = glist_findrtext(glist, x);
                if (yr) rtext_retext(yr);
Miller Puckette's avatar
Miller Puckette committed
        }
            /* if we made a new "pd" or changed a window name,
                update window list */
        if (natom2 >= 1  && vec2[0].a_type == A_SYMBOL
            && !strcmp(vec2[0].a_w.w_symbol->s_name, "pd"))
                canvas_updatewindowlist();
        /* this is a quick bugfix-- we need to free the binbuf "b" if we
           created a scalar in canvas_objtext */
        if (scalar_in_a_box)
        {
            binbuf_free(b);   
            scalar_in_a_box = 0;
        }
    else
    { // T_MESSAGE, T_TEXT, T_ATOM
        if (buf && x->te_type == T_TEXT)
            char *c;
            int n;
            for(c = buf, n = 0; n < bufsize; n++, c++)
            {
                if(*c == '\n')
                {
                    *c = '\v';
                }
            }
        }
        binbuf_gettext(x->te_binbuf, &c1, &i1);
        t_binbuf *b = binbuf_new();
        binbuf_text(b, buf, bufsize);
        binbuf_gettext(b, &c2, &i2);
        if (!c1 || strcmp(c1, c2))
        {
            canvas_undo_add(glist_getcanvas(glist), 10, "typing",
                (void *)canvas_undo_set_recreate(glist_getcanvas(glist),
                &x->te_g, pos));
            //fprintf(stderr,"blah |%s| |%s|\n", c1, buf);
        }
        binbuf_text(x->te_binbuf, buf, bufsize);
        binbuf_free(b);
        // we redraw retexted messages and comments so that they visually
        // match their stack position (namely, they are now on top)
        if (glist_istoplevel(glist))
        {
            gobj_vis(&x->te_g, glist, 0);
            gobj_vis(&x->te_g, glist, 1);
        }

        //probably don't need this here, but doesn't hurt to leave it in
        glob_preset_node_list_seek_hub();
        glob_preset_node_list_check_loc_and_update();
Miller Puckette's avatar
Miller Puckette committed
    /* this gets called when amessage gets sent to an object whose creation
    failed, presumably because of loading a patch with a missing extern or
    abstraction */
static void text_anything(t_text *x, t_symbol *s, int argc, t_atom *argv)
{
}

Miller Puckette's avatar
Miller Puckette committed
void g_text_setup(void)
{
    text_class = class_new(gensym("text"), 0, 0, sizeof(t_text),
        CLASS_NOINLET | CLASS_PATCHABLE, 0);
Miller Puckette's avatar
Miller Puckette committed
    class_addanything(text_class, text_anything);
Miller Puckette's avatar
Miller Puckette committed

    message_class = class_new(gensym("message"), 0, (t_method)message_free,
        sizeof(t_message), CLASS_PATCHABLE, 0);
    class_addbang(message_class, message_bang);
    class_addfloat(message_class, message_float);
    class_addsymbol(message_class, message_symbol);
    class_addblob(message_class, message_blob);
Miller Puckette's avatar
Miller Puckette committed
    class_addlist(message_class, message_list);
    class_addanything(message_class, message_list);

    class_addmethod(message_class, (t_method)message_click, gensym("click"),
        A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
    class_addmethod(message_class, (t_method)message_set, gensym("set"),
        A_GIMME, 0);
    class_addmethod(message_class, (t_method)message_add, gensym("add"),
        A_GIMME, 0);
    class_addmethod(message_class, (t_method)message_add2, gensym("add2"),
        A_GIMME, 0);
    class_addmethod(message_class, (t_method)message_addcomma,
        gensym("addcomma"), 0);
    class_addmethod(message_class, (t_method)message_addsemi,
        gensym("addsemi"), 0);
    class_addmethod(message_class, (t_method)message_adddollar,
        gensym("adddollar"), A_FLOAT, 0);
    class_addmethod(message_class, (t_method)message_adddollsym,
        gensym("adddollsym"), A_SYMBOL, 0);

    messresponder_class = class_new(gensym("messresponder"), 0, 0,
        sizeof(t_text), CLASS_PD, 0);
    class_addbang(messresponder_class, messresponder_bang);
    class_addfloat(messresponder_class, (t_method) messresponder_float);
    class_addsymbol(messresponder_class, messresponder_symbol);
    class_addlist(messresponder_class, messresponder_list);
    class_addanything(messresponder_class, messresponder_anything);

    gatom_class = class_new(gensym("gatom"), 0, (t_method)gatom_free,
        sizeof(t_gatom), CLASS_NOINLET | CLASS_PATCHABLE, 0);
    class_addbang(gatom_class, gatom_bang);
    class_addfloat(gatom_class, gatom_float);
    class_addsymbol(gatom_class, gatom_symbol);
    class_addlist(gatom_class, gatom_list);
    class_addmethod(gatom_class, (t_method)gatom_set, gensym("set"),
        A_GIMME, 0);
    class_addmethod(gatom_class, (t_method)gatom_click, gensym("click"),
        A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
    class_addmethod(gatom_class, (t_method)gatom_param, gensym("param"),
        A_GIMME, 0);
    class_setwidget(gatom_class, &gatom_widgetbehavior);
    class_setpropertiesfn(gatom_class, gatom_properties);
}