From bcca8885b9db87b66b47092d9e0d0c469631754c Mon Sep 17 00:00:00 2001 From: Ivica Ico Bukvic <ico@vt.edu> Date: Fri, 5 Sep 2014 20:02:36 -0400 Subject: [PATCH] *fixed regression where select all did not work *added ability to do shift+home and shift+end to select text inside objects *fixed manual resizing of subpatches which did not work in the current implementation. --- pd/src/g_canvas.c | 24 +++++++++++++++---- pd/src/g_editor.c | 12 ++++------ pd/src/g_readwrite.c | 2 ++ pd/src/g_rtext.c | 35 ++++++++++++++++++++++++++- pd/src/m_class.c | 29 ++++++++++++++-------- pd/src/pd.tk | 57 +++++++++++++++++--------------------------- 6 files changed, 102 insertions(+), 57 deletions(-) diff --git a/pd/src/g_canvas.c b/pd/src/g_canvas.c index a6c521471..fadc9f7e2 100644 --- a/pd/src/g_canvas.c +++ b/pd/src/g_canvas.c @@ -357,6 +357,15 @@ void canvasgop__motionhook(t_scalehandle *sh,t_floatarg f1, t_floatarg f2); tells us which.) */ t_canvas *canvas_new(void *dummy, t_symbol *sel, int argc, t_atom *argv) { + /* DEBUG + int d; + for (d=0; d < argc; d++) + { + if (argv[d].a_type == A_FLOAT) + fprintf(stderr, " %g ", argv[d].a_w.w_float); + else fprintf(stderr, " %s ", argv[d].a_w.w_symbol->s_name); + } + fprintf(stderr,"\n");*/ t_canvas *x = (t_canvas *)pd_new(canvas_class); t_canvas *owner = canvas_getcurrent(); t_symbol *s = &s_; @@ -1047,6 +1056,7 @@ void canvas_objfor(t_glist *gl, t_text *x, int argc, t_atom *argv); void canvas_restore(t_canvas *x, t_symbol *s, int argc, t_atom *argv) { t_pd *z; + //fprintf(stderr,"canvas_restore %lx\n", x); /* for [group] we add an inlet to the svg attr proxy */ if (argc > 2 && argv[2].a_w.w_symbol == gensym("group")) { @@ -1868,10 +1878,12 @@ int canvas_open(t_canvas *x, const char *name, const char *ext, return(result); } +extern t_symbol *last_typedmess; // see g_readwrite.c for the explanation of this ugly hack + static void canvas_f(t_canvas *x, t_symbol *s, int argc, t_atom *argv) { static int warned; - //fprintf(stderr,"canvas_f .x%lx\n", (t_int)x); + //fprintf(stderr,"canvas_f %lx %d current=%lx %s\n", (t_int)x, argc, canvas_getcurrent(), last_typedmess != NULL ? last_typedmess->s_name : "none"); t_canvas *xp = x; //parent window for a special case dealing with subpatches t_gobj *g, *g2; t_object *ob; @@ -1880,10 +1892,12 @@ static void canvas_f(t_canvas *x, t_symbol *s, int argc, t_atom *argv) post("** ignoring width or font settings from future Pd version **"); warned = 1; } - if (!x->gl_list) { + // if we are either an empty canvas or are a part of a restore message of a subpatch + if (!x->gl_list || !strcmp(last_typedmess->s_name, "restore")) { if (x->gl_owner && !x->gl_isgraph) { - // this means that we are a canvas that was just created - // and that our width applies to our appearance on our parent + // this means that we are a canvas that was just created or have just + // fnished restoring and that our width applies to our appearance on + // our parent xp = x->gl_owner; for (g = xp->gl_list; g != (t_gobj *)x; g = g->g_next) { //fprintf(stderr,".x%lx .x%lx\n", (t_int)g, (t_int)x); @@ -1894,6 +1908,7 @@ static void canvas_f(t_canvas *x, t_symbol *s, int argc, t_atom *argv) } else { for (g = x->gl_list; g2 = g->g_next; g = g2) ; + //fprintf(stderr,"same canvas .x%lx .x%lx\n", (t_int)g, (t_int)x); } //fprintf(stderr,"is canvas_class? %d\n", (pd_class(&g->g_pd) == canvas_class ? 1:0)); if ((ob = pd_checkobject(&g->g_pd)) || pd_class(&g->g_pd) == canvas_class) @@ -1904,6 +1919,7 @@ static void canvas_f(t_canvas *x, t_symbol *s, int argc, t_atom *argv) { gobj_vis(g, xp, 0); gobj_vis(g, xp, 1); + gobj_select(g, xp, 1); } } } diff --git a/pd/src/g_editor.c b/pd/src/g_editor.c index 4fab6b991..1a81ba19e 100644 --- a/pd/src/g_editor.c +++ b/pd/src/g_editor.c @@ -4767,6 +4767,7 @@ void canvas_key(t_canvas *x, t_symbol *s, int ac, t_atom *av) if (av[1].a_type == A_SYMBOL) { gotkeysym = av[1].a_w.w_symbol; + //fprintf(stderr,"gotkeysym=%s\n", gotkeysym->s_name); } else if (av[1].a_type == A_FLOAT) { @@ -4854,14 +4855,11 @@ void canvas_key(t_canvas *x, t_symbol *s, int ac, t_atom *av) || !strcmp(gotkeysym->s_name, "Down") || !strcmp(gotkeysym->s_name, "Left") || !strcmp(gotkeysym->s_name, "Right") - || !strcmp(gotkeysym->s_name, "CtrlLeft") - || !strcmp(gotkeysym->s_name, "CtrlRight") - || !strcmp(gotkeysym->s_name, "ShiftLeft") - || !strcmp(gotkeysym->s_name, "ShiftRight") - || !strcmp(gotkeysym->s_name, "CtrlShiftLeft") - || !strcmp(gotkeysym->s_name, "CtrlShiftRight") || !strcmp(gotkeysym->s_name, "Home") - || !strcmp(gotkeysym->s_name, "End"))) + || !strcmp(gotkeysym->s_name, "End") + || !strncmp("Ctrl", gotkeysym->s_name, 4) + || !strncmp("CtrlShift", gotkeysym->s_name, 9) + || !strncmp("Shift", gotkeysym->s_name, 5))) { /* send the key to the box's editor */ /*if (!x->gl_editor->e_textdirty) diff --git a/pd/src/g_readwrite.c b/pd/src/g_readwrite.c index c02fddfc3..c0c8be9ad 100644 --- a/pd/src/g_readwrite.c +++ b/pd/src/g_readwrite.c @@ -615,6 +615,7 @@ static void canvas_saveto(t_canvas *x, t_binbuf *b) if (x->gl_owner && !x->gl_env) { /* have to go to original binbuf to find out how we were named. */ + //fprintf(stderr,"saving subpatch\n"); t_binbuf *bz = binbuf_new(); t_symbol *patchsym; binbuf_addbinbuf(bz, x->gl_obj.ob_binbuf); @@ -627,6 +628,7 @@ static void canvas_saveto(t_canvas *x, t_binbuf *b) (int)(x->gl_screeny2 - x->gl_screeny1), (patchsym != &s_ ? patchsym: gensym("(subpatch)")), x->gl_mapped); + t_text *xt = (t_text *)x; } /* root or abstraction */ else diff --git a/pd/src/g_rtext.c b/pd/src/g_rtext.c index c93747ce1..6b72a1f61 100644 --- a/pd/src/g_rtext.c +++ b/pd/src/g_rtext.c @@ -512,11 +512,15 @@ void rtext_select(t_rtext *x, int state) void rtext_activate(t_rtext *x, int state) { + //fprintf(stderr,"rtext_activate\n"); int w = 0, h = 0, indx; t_glist *glist = x->x_glist; t_canvas *canvas = glist_getcanvas(glist); //if (state && x->x_active) printf("duplicate rtext_activate\n"); - if (state == x->x_active) return; // avoid excess calls + // the following prevents from selecting all when inside an + // object that is already being text for... please *test* + // "fixes" before committing them + //if (state == x->x_active) return; // avoid excess calls if (state) { sys_vgui(".x%lx.c focus %s\n", canvas, x->x_tag); @@ -549,6 +553,7 @@ static int rtext_compare_special_chars(const char c) void rtext_key(t_rtext *x, int keynum, t_symbol *keysym) { + //fprintf(stderr,"rtext_key %d %s\n", keynum, keysym->s_name); int w = 0, h = 0, indx, i, newsize, ndel; if (keynum) { @@ -697,6 +702,20 @@ be printable in whatever 8-bit character set we find ourselves. */ x->x_selend = x->x_selstart; last_sel = 0; } + else if (!strcmp(keysym->s_name, "ShiftHome")) + { + if (x->x_selstart) + { + if (last_sel == 2) + x->x_selend = x->x_selstart; + u8_dec(x->x_buf, &x->x_selstart); + last_sel = 1; + } + while (x->x_selstart > 0 && x->x_buf[x->x_selstart] != '\n') + u8_dec(x->x_buf, &x->x_selstart); + //x->x_selend = x->x_selstart; + //last_sel = 1; + } else if (!strcmp(keysym->s_name, "End")) { while (x->x_selend < x->x_bufsize && @@ -707,6 +726,20 @@ be printable in whatever 8-bit character set we find ourselves. */ x->x_selstart = x->x_selend; last_sel = 0; } + else if (!strcmp(keysym->s_name, "ShiftEnd")) + { + if (last_sel == 1) + x->x_selstart = x->x_selend; + while (x->x_selend < x->x_bufsize && + x->x_buf[x->x_selend] != '\n') + u8_inc(x->x_buf, &x->x_selend); + if (x->x_selend < x->x_bufsize) + { + u8_inc(x->x_buf, &x->x_selend); + } + //x->x_selstart = x->x_selend; + last_sel = 2; + } else if (!strcmp(keysym->s_name, "CtrlLeft")) { /* first find first non-space char going back */ diff --git a/pd/src/m_class.c b/pd/src/m_class.c index 7d1c4779e..5678a92e3 100644 --- a/pd/src/m_class.c +++ b/pd/src/m_class.c @@ -660,7 +660,7 @@ t_symbol s__X = {"#X", 0, 0}; t_symbol s_x = {"x", 0, 0}; t_symbol s_y = {"y", 0, 0}; t_symbol s_ = {"", 0, 0}; -t_symbol s_blob = {"blob", 0, 0}; /* MP 20061223 blob type */ +t_symbol s_blob = {"blob", 0, 0}; /* MP 20061223 blob type */ static t_symbol *symlist[] = { &s_pointer, &s_float, &s_symbol, &s_bang, &s_list, &s_anything, &s_signal, &s__N, &s__X, &s_x, &s_y, &s_, &s_blob}; /* MP 20061223 added s_blob */ @@ -713,6 +713,12 @@ typedef t_pd *(*t_fun6)(t_int i1, t_int i2, t_int i3, t_int i4, t_int i5, t_int /* needed for proper error reporting */ extern t_pd *pd_mess_from_responder(t_pd *x); +// hackish way to figure out what was the last command we invoked so that commands +// that follow it (via commas, like the new width ability), can understand whom +// they belong to. This is a problem with subpatches whose values get assigned to +// their last created object, as opposed themselves +t_symbol *last_typedmess; + void pd_typedmess(t_pd *x, t_symbol *s, int argc, t_atom *argv) { t_class *c = *x; @@ -724,7 +730,7 @@ void pd_typedmess(t_pd *x, t_symbol *s, int argc, t_atom *argv) int narg = 0; t_pd *bonzo; - //fprintf(stderr,"\nstart %s %d\n", s->s_name, c->c_nmethod); + //fprintf(stderr,"pd_typedmess: %s %d\n", s->s_name, c->c_nmethod); /* check for messages that are handled by fixed slots in the class structure. We don't catch "pointer" though so that sending "pointer" @@ -735,17 +741,17 @@ void pd_typedmess(t_pd *x, t_symbol *s, int argc, t_atom *argv) else if (argv->a_type == A_FLOAT) (*c->c_floatmethod)(x, argv->a_w.w_float); else goto badarg; - return; + goto lastmess; } if (s == &s_bang) { (*c->c_bangmethod)(x); - return; + goto lastmess; } if (s == &s_list) { (*c->c_listmethod)(x, s, argc, argv); - return; + goto lastmess; } if (s == &s_symbol) { @@ -753,14 +759,14 @@ void pd_typedmess(t_pd *x, t_symbol *s, int argc, t_atom *argv) (*c->c_symbolmethod)(x, argv->a_w.w_symbol); else (*c->c_symbolmethod)(x, &s_); - return; + goto lastmess; } if (s == &s_blob) /* MP 20061226 blob type */ { /*post("pd_typedmess argc = %d\n", argc);*//* MP 20061226 debug */ if (argc == 1) (*c->c_blobmethod)(x, argv->a_w.w_blob); else goto badarg; - return; + goto lastmess; } for (i = c->c_nmethod, m = c->c_methods; i--; m++) { @@ -774,7 +780,7 @@ void pd_typedmess(t_pd *x, t_symbol *s, int argc, t_atom *argv) if (x == &pd_objectmaker) newest = (*((t_newgimme)(m->me_fun)))(s, argc, argv); else (*((t_messgimme)(m->me_fun)))(x, s, argc, argv); - return; + goto lastmess; } if (argc > MAXPDARG) argc = MAXPDARG; if (x != &pd_objectmaker) *(ap++) = (t_int)x, narg++; @@ -874,11 +880,11 @@ void pd_typedmess(t_pd *x, t_symbol *s, int argc, t_atom *argv) } if (x == &pd_objectmaker) newest = bonzo; - return; + goto lastmess; } } (*c->c_anymethod)(x, s, argc, argv); - return; + goto lastmess; badarg: /* if x is a messresponder class, tweak it to point to the message that contains it (so it can be selected when 'Find @@ -886,6 +892,9 @@ badarg: x = pd_mess_from_responder(x); pd_error(x, "Bad arguments for message '%s' to object '%s'", s->s_name, c->c_name->s_name); +lastmess: + last_typedmess = s; + return; } /* convenience routine giving a stdarg interface to typedmess(). Only diff --git a/pd/src/pd.tk b/pd/src/pd.tk index f3a9daae5..48748edaa 100644 --- a/pd/src/pd.tk +++ b/pd/src/pd.tk @@ -4646,41 +4646,28 @@ proc pdtk_canvas_sendkey {name state key iso shift focus serial} { #puts stderr "shift=$shift ctrl=$ctrl key=$key" - #if {[string match Home $key] && $ctrl} { - # set key "CtrlHome" - # set state 1 - #} - - #if {[string match End $key] && $ctrl} { - # set key "CtrlEnd" - # set state 1 - #} - - if {[string match Left $key]} { - if {$ctrl == 1 && $shift == 0} { - set key "CtrlLeft" - set state 1 - } - if {$ctrl == 0 && $shift == 1} { - set key "ShiftLeft" - } - if {$ctrl == 1 && $shift == 1} { - set key "CtrlShiftLeft" - set state 1 - } - } - - if {[string match Right $key]} { - if {$ctrl == 1 && $shift == 0} { - set key "CtrlRight" - set state 1 - } - if {$ctrl == 0 && $shift == 1} { - set key "ShiftRight" - } - if {$ctrl == 1 && $shift == 1} { - set key "CtrlShiftRight" - set state 1 + switch -- $key { + Left - + Right - + Up - + Down - + Home - + End - + Next - + Prior { + if {$ctrl == 1 && $shift == 0} { + set key "Ctrl$key" + set state 1 + } + if {$ctrl == 0 && $shift == 1} { + set key "Shift$key" + #set state 1 (this results in a double press) + } + if {$ctrl == 1 && $shift == 1} { + set key "CtrlShift$key" + set state 1 + } + #puts stderr "outcome=$key" } } -- GitLab