From 1c556bac125fb53c443f3274c1c7a5d82abf8441 Mon Sep 17 00:00:00 2001 From: Ivica Ico Bukvic <ico@vt.edu> Date: Wed, 30 Nov 2011 01:46:16 -0500 Subject: [PATCH] Fixed nasty bug where doubly-embedded pd canvases (not abstractions) did not redraw properly (affects all known versions of pd) plus additional clean-up and improvements on the gop redrawing/apply logic including ability to limit minimum size on gop-enabled objects without parents that also do not have hidetext enabled. --- src/g_canvas.c | 19 ++++++------ src/g_editor.c | 45 ++++++++++++++++++++++------- src/g_graph.c | 78 ++++++++++++++++++++++++++++++++++++++++---------- src/g_rtext.c | 7 +++-- src/g_text.c | 3 ++ 5 files changed, 116 insertions(+), 36 deletions(-) diff --git a/src/g_canvas.c b/src/g_canvas.c index 391429ec7..1b7fa0c77 100644 --- a/src/g_canvas.c +++ b/src/g_canvas.c @@ -1753,24 +1753,27 @@ void canvasgop_draw_move(t_canvas *x, int doit) if (x->gl_havewindow) { canvas_redraw(x); } - if (x->gl_owner && glist_isvisible(x->gl_owner)) - { + //fprintf(stderr,"%d %d\n", (x->gl_owner ? 1:0), glist_isvisible(x->gl_owner)); + + if (x->gl_owner && glist_isvisible(x->gl_owner)) { glist_noselect(x); + //vmess(&x->gl_owner->gl_obj.te_pd, gensym("menu-open"), ""); gobj_vis(&x->gl_gobj, x->gl_owner, 0); gobj_vis(&x->gl_gobj, x->gl_owner, 1); - canvas_redraw(x->gl_owner); + //canvas_redraw(x->gl_owner); } //update scrollbars when GOP potentially exceeds window size t_canvas *canvas=(t_canvas *)glist_getcanvas(x); //if gop is being disabled go one level up - if (!x->gl_isgraph && x->gl_owner) { + if (!x->gl_isgraph && x->gl_owner && glist_isvisible(x->gl_owner)) { canvas=canvas->gl_owner; - canvas_redraw(canvas); + //canvas_redraw(canvas); } sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", (t_int)x); - sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", (t_int)canvas); + if (x->gl_owner && glist_isvisible(x->gl_owner)) + sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", (t_int)x->gl_owner); } extern int gfxstub_haveproperties(void *key); @@ -1805,8 +1808,8 @@ void canvasgop__clickhook(t_scalehandle *sh, t_floatarg f, t_floatarg xxx, t_flo // check if the text is not hidden // if so make minimum width and height based retrieved from getrect - if (x->gl_hidetext == 0 && x->gl_owner) { - gobj_getrect((t_gobj*)x, x->gl_owner, &x1, &y1, &x2, &y2); + if (!x->gl_hidetext) { + gobj_getrect((t_gobj*)x, (x->gl_owner ? x->gl_owner : x), &x1, &y1, &x2, &y2); if (x2-x1 > x->gl_pixwidth) x->gl_pixwidth = x2-x1; if (y2-y1 > x->gl_pixheight) x->gl_pixheight = y2-y1; } diff --git a/src/g_editor.c b/src/g_editor.c index 201827101..c3f48c596 100644 --- a/src/g_editor.c +++ b/src/g_editor.c @@ -1778,16 +1778,8 @@ void canvas_properties(t_glist *x) static void canvas_donecanvasdialog(t_glist *x, t_symbol *s, int argc, t_atom *argv) { - /* parent windows are treated differently than applies to individual objects */ - if (glist_getcanvas(x) != x && !canvas_isabstraction(x)) { - canvas_apply_setundo(glist_getcanvas(x), (t_gobj *)x); - } - else { - canvas_canvas_setundo(x); - //fprintf(stderr,"canvas_apply_undo\n"); - } - - t_float xperpix, yperpix, x1, y1, x2, y2, xpix, ypix, xmargin, ymargin; + t_float xperpix, yperpix, x1, y1, x2, y2, xpix, ypix, xmargin, ymargin; + int rx1=0, ry1=0, rx2=0, ry2=0; //for getrect int graphme, redraw = 0; xperpix = atom_getfloatarg(0, argc, argv); @@ -1803,6 +1795,18 @@ static void canvas_donecanvasdialog(t_glist *x, xmargin = atom_getfloatarg(9, argc, argv); ymargin = atom_getfloatarg(10, argc, argv); + /* parent windows are treated differently than applies to individual objects */ + if (glist_getcanvas(x) != x && !canvas_isabstraction(x)) { + canvas_apply_setundo(glist_getcanvas(x), (t_gobj *)x); + } + else /*if (x1!=x->gl_x1 || x2!=x->gl_x2 || y1!=x->gl_y1 || y2!=x->gl_y2 || + graphme!=(x->gl_isgraph+2*x->gl_hidetext) || x->gl_pixwidth!=xpix || + x->gl_pixheight!=ypix || x->gl_xmargin!=xmargin || x->gl_ymargin!=ymargin) {*/ + { + canvas_canvas_setundo(x); + //fprintf(stderr,"canvas_apply_undo\n"); + } + x->gl_pixwidth = xpix; x->gl_pixheight = ypix; x->gl_xmargin = xmargin; @@ -1848,9 +1852,27 @@ static void canvas_donecanvasdialog(t_glist *x, x->gl_y2 = x->gl_y1 + yperpix; } } + /* LATER avoid doing 2 redraws here (possibly one inside setgraph) */ canvas_setgraph(x, graphme, 0); canvas_dirty(x, 1); + + // make sure gop is never smaller than its text + // if one wants smaller gop window, make sure to disable text + if (x->gl_isgraph && !x->gl_hidetext) { + //fprintf(stderr, "check size\n"); + gobj_getrect((t_gobj*)x, (x->gl_owner ? x->gl_owner : x), &rx1, &ry1, &rx2, &ry2); + //fprintf(stderr,"%d %d %d %d\n", rx1, rx2, ry1, ry2); + if (rx2-rx1 > x->gl_pixwidth) { + x->gl_pixwidth = rx2-rx1; + //fprintf(stderr,"change width\n"); + } + if (ry2-ry1 > x->gl_pixheight) { + x->gl_pixheight = ry2-ry1; + //fprintf(stderr,"change height\n"); + } + } + if (x->gl_havewindow) { //fprintf(stderr,"donecanvasdialog canvas_redraw\n"); canvas_redraw(x); @@ -4063,7 +4085,8 @@ void canvas_editmode(t_canvas *x, t_floatarg fyesplease) } x->gl_edit = !x->gl_edit; if (x->gl_edit && glist_isvisible(x) && glist_istoplevel(x)){ - if (x->gl_goprect) canvas_draw_gop_resize_hooks(x); // dpsaha@vt.edu add the resize blobs on GOP + //dpsaha@vt.edu add the resize blobs on GOP + if (x->gl_goprect) canvas_draw_gop_resize_hooks(x); canvas_setcursor(x, CURSOR_EDITMODE_NOTHING); } else diff --git a/src/g_graph.c b/src/g_graph.c index f48b0f114..23fccfd76 100644 --- a/src/g_graph.c +++ b/src/g_graph.c @@ -211,9 +211,12 @@ void glist_grab(t_glist *x, t_gobj *y, t_glistmotionfn motionfn, t_canvas *glist_getcanvas(t_glist *x) { + //fprintf(stderr,"gobj_shouldvis\n"); while (x->gl_owner && !x->gl_havewindow && x->gl_isgraph && - gobj_shouldvis(&x->gl_gobj, x->gl_owner)) + gobj_shouldvis(&x->gl_gobj, x->gl_owner)) { x = x->gl_owner; + //fprintf(stderr,"+\n"); + } return((t_canvas *)x); } @@ -734,7 +737,8 @@ int garray_getname(t_garray *x, t_symbol **namep); static void graph_vis(t_gobj *gr, t_glist *parent_glist, int vis) { t_glist *x = (t_glist *)gr; - char tag[50]; + //fprintf(stderr,"graph_vis gr=.x%lx parent_glist=.x%lx glist_getcanvas(x->gl_owner)=.x%lx vis=%d\n", (t_int)gr, (t_int)parent_glist, (t_int)glist_getcanvas(x->gl_owner), vis); + char tag[50]; t_gobj *g; int x1, y1, x2, y2; /* ordinary subpatches: just act like a text object */ @@ -744,9 +748,20 @@ static void graph_vis(t_gobj *gr, t_glist *parent_glist, int vis) return; } - if (vis && canvas_showtext(x)) + // weird exception + //int exception = 0; + //t_canvas* tgt = glist_getcanvas(x->gl_owner); + //if (parent_glist->gl_owner && !parent_glist->gl_mapped && + // parent_glist->gl_owner->gl_mapped) { + // tgt = parent_glist; + // exception = 1; + //} + //fprintf(stderr,"tgt=.x%lx %d\n", (t_int)tgt, exception); + + if (vis && canvas_showtext(x) && gobj_shouldvis(gr, parent_glist)) rtext_draw(glist_findrtext(parent_glist, &x->gl_obj)); graph_getrect(gr, parent_glist, &x1, &y1, &x2, &y2); + //fprintf(stderr,"%d %d %d %d\n", x1, y1, x2, y2); if (!vis) rtext_erase(glist_findrtext(parent_glist, &x->gl_obj)); @@ -761,18 +776,20 @@ static void graph_vis(t_gobj *gr, t_glist *parent_glist, int vis) just show the bounding rectangle */ if (x->gl_havewindow) { - if (vis) - { - sys_vgui(".x%lx.c create polygon\ - %d %d %d %d %d %d %d %d %d %d -tags %s -fill #c0c0c0\n", - glist_getcanvas(x->gl_owner), - x1, y1, x1, y2, x2, y2, x2, y1, x1, y1, tag); - } - else - { - sys_vgui(".x%lx.c delete %s\n", - glist_getcanvas(x->gl_owner), tag); - } + if (vis && gobj_shouldvis(gr, parent_glist)) + { + sys_vgui("catch {.x%lx.c create polygon\ + %d %d %d %d %d %d %d %d %d %d -tags %s -fill #c0c0c0}\n", + glist_getcanvas(x->gl_owner), + //parent_glist, + x1, y1, x1, y2, x2, y2, x2, y1, x1, y1, tag); + } + else if (gobj_shouldvis(gr, parent_glist)) + { + sys_vgui("catch {.x%lx.c delete %s}\n", + glist_getcanvas(x->gl_owner), tag); + //parent_glist, tag); + } return; } /* otherwise draw (or erase) us as a graph inside another glist. */ @@ -938,6 +955,7 @@ static void graph_getrect(t_gobj *z, t_glist *glist, { //fprintf(stderr,"graph_getrect\n"); int x1 = 0x7fffffff, y1 = 0x7fffffff, x2 = -0x7fffffff, y2 = -0x7fffffff; + int tx1 = 0x7fffffff, ty1 = 0x7fffffff, tx2 = -0x7fffffff, ty2 = -0x7fffffff; t_glist *x = (t_glist *)z; if (x->gl_isgraph) { @@ -947,6 +965,7 @@ static void graph_getrect(t_gobj *z, t_glist *glist, int x21, y21, x22, y22; graph_graphrect(z, glist, &x1, &y1, &x2, &y2); + //fprintf(stderr,"%d %d %d %d\n", x1, y1, x2, y2); if (canvas_showtext(x)) { @@ -955,6 +974,7 @@ static void graph_getrect(t_gobj *z, t_glist *glist, x2 = x22; if (y22 > y2) y2 = y22; + //fprintf(stderr,"canvas_showtext %d %d %d %d\n", x1, y1, x2, y2); } if (!x->gl_goprect) { @@ -979,6 +999,34 @@ static void graph_getrect(t_gobj *z, t_glist *glist, } x->gl_havewindow = hadwindow; } + + //fprintf(stderr,"%d %d %d %d\n", x1, y1, x2, y2); + + // check if the text is not hidden and if so use that as the limit of the gop's size + if (!x->gl_hidetext) { + text_widgetbehavior.w_getrectfn(z, glist, &x21, &y21, &x22, &y22); + if (x22 > x2) + x2 = x22; + if (y22 > y2) + y2 = y22; + // WARNING: ugly hack trying to replicate rtext_senditup if we have no parent + // later consider instead of hardwiring values pulling these more intelligently from + // a common place + int fw = sys_fontwidth(x->gl_font); + int fh = sys_fontheight(x->gl_font); + //fprintf(stderr," fw=%d /=%d mod=%d \n", fw, fw/60, fw%60); + //fprintf(stderr,"name=%s\n",x->gl_name->s_name); + int tcols = strlen(x->gl_name->s_name) - 3; + int th = fh + fh * (tcols/60) + 4; + if (tcols > 60) tcols = 60; + int tw = fw * tcols + 4; + if (tw + x1 > x2) + x2 = tw + x1; + if (th + y1 > y2) + y2 = th + y1; + //fprintf(stderr,"graph_getrect->text_getrect %d=%d %d=%d\n", fw, x2, fh, y2); + } + /* fix visibility of edge items for garrays */ int has_garray = 0; for (g = x->gl_list; g; g = g->g_next) { diff --git a/src/g_rtext.c b/src/g_rtext.c index a8efb11d2..82bdce63a 100644 --- a/src/g_rtext.c +++ b/src/g_rtext.c @@ -157,6 +157,7 @@ extern int sys_oldtclversion; static void rtext_senditup(t_rtext *x, int action, int *widthp, int *heightp, int *indexp) { + //fprintf(stderr,"rtext_senditup\n"); if (x) { t_float dispx, dispy; char smallbuf[200], *tempbuf; @@ -244,13 +245,15 @@ static void rtext_senditup(t_rtext *x, int action, int *widthp, int *heightp, pixwide = ncolumns * fontwidth + (LMARGIN + RMARGIN); pixhigh = nlines * fontheight + (TMARGIN + BMARGIN); - if (action == SEND_FIRST) + if (action == SEND_FIRST) { + //fprintf(stderr,"canvas=.x%lx %s\n", (t_int)canvas, tempbuf); sys_vgui("pdtk_text_new .x%lx.c %s %f %f {%.*s} %d %s\n", canvas, x->x_tag, dispx + LMARGIN, dispy + TMARGIN, outchars, tempbuf, sys_hostfontsize(font), (glist_isselected(x->x_glist, &x->x_glist->gl_gobj)? "$select_color" : "$text_color")); + } else if (action == SEND_UPDATE) { /*fprintf(stderr, "SEND_UPDATE canvas_class=%d isgraph=%d goprect=%d\n", @@ -355,7 +358,7 @@ void rtext_retext(t_rtext *x) /* find the rtext that goes with a text item */ t_rtext *glist_findrtext(t_glist *gl, t_text *who) { - t_rtext *x; + t_rtext *x=NULL; if (!gl->gl_editor) canvas_create_editor(gl); if (gl->gl_editor->e_rtext) diff --git a/src/g_text.c b/src/g_text.c index b04daff19..649c58fd8 100644 --- a/src/g_text.c +++ b/src/g_text.c @@ -1041,6 +1041,7 @@ static void gatom_properties(t_gobj *z, t_glist *owner) static void text_getrect(t_gobj *z, t_glist *glist, int *xp1, int *yp1, int *xp2, int *yp2) { + //fprintf(stderr,"text_getrect %d %d\n", (glist->gl_editor ? 1 : 0), (glist->gl_editor->e_rtext ? 1:0)); t_text *x = (t_text *)z; int width, height, iscomment = (x->te_type == T_TEXT); t_float x1, y1, x2, y2; @@ -1075,6 +1076,8 @@ static void text_getrect(t_gobj *z, t_glist *glist, t_rtext *y = glist_findrtext(glist, x); width = rtext_width(y); + //fprintf(stderr,"width=%d\n", width); + /* 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 -- GitLab