From 40e33c4ac85cecbf8d9436c32dc31992b048af17 Mon Sep 17 00:00:00 2001 From: Ivica Ico Bukvic <ico@vt.edu> Date: Wed, 19 Nov 2014 01:32:46 -0500 Subject: [PATCH] *added legacy behavior for key* family of objects where autorepeat is observed (just create an object with an optional argument of 1) *fixed bug where gatom after pressing return should not stay focused *fixed bug where gatom's number after ctrl+click should not turn selected *offered ability for image and others to ignore clicks and pass them below (measured by a zero width, only works for single inlet/outlet objects as otherwise their multiple inlets or outlets will be truncated to the same spot) *reenabled ability for cnv to pass clicks below and reflected this in the official help file (separate previous commit) --- pd/src/g_editor.c | 37 +++++++++++++++++++++++++++---- pd/src/g_graph.c | 6 ++++-- pd/src/g_text.c | 15 +++++++++---- pd/src/x_gui.c | 55 ++++++++++++++++++++++++++++++++++++----------- 4 files changed, 91 insertions(+), 22 deletions(-) diff --git a/pd/src/g_editor.c b/pd/src/g_editor.c index fc814ed00..58ff2c21c 100644 --- a/pd/src/g_editor.c +++ b/pd/src/g_editor.c @@ -2218,7 +2218,12 @@ int canvas_hitbox(t_canvas *x, t_gobj *y, int xpos, int ypos, if (!gobj_shouldvis(y, x)) return (0); gobj_getrect(y, x, &x1, &y1, &x2, &y2); - if (xpos >= x1 && xpos <= x2 && ypos >= y1 && ypos <= y2) + // we also add a check that width is greater than 0 because we use this + // to return value from objects that are designed to ignore clicks and + // pass them below, e.g. pd-l2ork's version of ggee/image which uses this + // feature in runtime mode only (we can use canvas->gl_edit check for this + // within an external) + if (x2-x1 > 0 && xpos >= x1 && xpos <= x2 && ypos >= y1 && ypos <= y2) { *x1p = x1; *y1p = y1; @@ -3017,6 +3022,8 @@ static double canvas_upclicktime; static int canvas_upx, canvas_upy; #define DCLICKINTERVAL 0.25 +extern t_class *my_canvas_class; // for ignoring runtime clicks + /* mouse click */ void canvas_doclick(t_canvas *x, int xpos, int ypos, int which, int mod, int doit) @@ -3129,8 +3136,8 @@ void canvas_doclick(t_canvas *x, int xpos, int ypos, int which, if (canvas_hitbox(x, y, xpos, ypos, &x1, &y1, &x2, &y2)) { ob = pd_checkobject(&y->g_pd); - /* do not give clicks to comments during runtime */ - if (!ob || ob->te_type != T_TEXT) + /* do not give clicks to comments or cnv during runtime */ + if (!ob || (ob->te_type != T_TEXT && ob->ob_pd != my_canvas_class)) yclick = y; //fprintf(stderr," MAIN found clickable %d\n", // clickreturned); @@ -4760,6 +4767,7 @@ void canvas_displaceselection(t_canvas *x, int dx, int dy) void canvas_key(t_canvas *x, t_symbol *s, int ac, t_atom *av) { static t_symbol *keynumsym, *keyupsym, *keynamesym; + static t_symbol *keynumsym_a, *keyupsym_a, *keynamesym_a; int keynum; t_symbol *gotkeysym; @@ -4844,6 +4852,10 @@ void canvas_key(t_canvas *x, t_symbol *s, int ac, t_atom *av) keynumsym = gensym("#key"); keyupsym = gensym("#keyup"); keynamesym = gensym("#keyname"); + + keynumsym_a = gensym("#key_a"); + keyupsym_a = gensym("#keyup_a"); + keynamesym_a = gensym("#keyname_a"); } #ifdef __APPLE__ if (keynum == 30) @@ -4855,6 +4867,10 @@ void canvas_key(t_canvas *x, t_symbol *s, int ac, t_atom *av) else if (keynum == 29) keynum = 0, gotkeysym = gensym("Right"); #endif + // set the shared variable for broadcasting of keypresses to key et al. objectss + t_atom at[2]; + + // now broadcast key press to key et al. objects if (!autorepeat) { if (keynumsym->s_thing && down) @@ -4863,13 +4879,26 @@ void canvas_key(t_canvas *x, t_symbol *s, int ac, t_atom *av) pd_float(keyupsym->s_thing, (t_float)keynum); if (keynamesym->s_thing) { - t_atom at[2]; at[0] = av[0]; SETFLOAT(at, down); SETSYMBOL(at+1, gotkeysym); pd_list(keynamesym->s_thing, 0, 2, at); } } + + // now do the same for autorepeat-enabled objects (key et al. alternative behavior) + if (keynumsym_a->s_thing && down) + pd_float(keynumsym_a->s_thing, (t_float)keynum); + if (keyupsym_a->s_thing && !down) + pd_float(keyupsym_a->s_thing, (t_float)keynum); + if (keynamesym_a->s_thing) + { + at[0] = av[0]; + SETFLOAT(at, down); + SETSYMBOL(at+1, gotkeysym); + pd_list(keynamesym_a->s_thing, 0, 2, at); + } + if (!x->gl_editor) /* if that 'invis'ed the window, we'd better stop. */ return; if (x && down) diff --git a/pd/src/g_graph.c b/pd/src/g_graph.c index 0a62b4c75..6c1b05bdf 100644 --- a/pd/src/g_graph.c +++ b/pd/src/g_graph.c @@ -1483,6 +1483,8 @@ static void graph_motion(void *z, t_floatarg dx, t_floatarg dy) garray_redraw(a); } +extern t_class *my_canvas_class; // for ignoring runtime clicks + static int graph_click(t_gobj *z, struct _glist *glist, int xpix, int ypix, int shift, int alt, int dbl, int doit) { @@ -1517,8 +1519,8 @@ static int graph_click(t_gobj *z, struct _glist *glist, if (canvas_hitbox(x, y, xpix, ypix, &x1, &y1, &x2, &y2)) { ob = pd_checkobject(&y->g_pd); - /* do not give clicks to comments during runtime */ - if (!ob || ob->te_type != T_TEXT) + /* do not give clicks to comments or cnv during runtime */ + if (!ob || (ob->te_type != T_TEXT && ob->ob_pd != my_canvas_class)) clickme = y; //fprintf(stderr," found clickable %d\n", clickreturned); } diff --git a/pd/src/g_text.c b/pd/src/g_text.c index 86f6f2e99..84a72926c 100644 --- a/pd/src/g_text.c +++ b/pd/src/g_text.c @@ -884,7 +884,12 @@ static void gatom_set(t_gatom *x, t_symbol *s, int argc, t_atom *argv) 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) - gatom_retext(x, 1, 0); + { + 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); + } x->a_buf[0] = 0; } @@ -1017,6 +1022,7 @@ static void gatom_key(void *z, t_floatarg f) gatom_bang(x); gatom_retext(x, 1, 1); x->a_buf[0] = 0; + glist_grab(x->a_glist, 0, 0, 0, 0, 0); } else if (len < (ATOMBUFSIZE-1)) { @@ -1072,9 +1078,10 @@ static void gatom_click(t_gatom *x, { x->a_toggle = x->a_atom.a_w.w_float; gatom_float(x, 0); - return; } else gatom_float(x, x->a_toggle); + gatom_retext(x, 0, 1); + return; } x->a_shift = shift; x->a_buf[0] = 0; @@ -1713,11 +1720,11 @@ static int text_click(t_gobj *z, struct _glist *glist, t_rtext *y = glist_findrtext(glist, x); if (doit) { - gatom_click((t_gatom *)x, (t_floatarg)xpix, (t_floatarg)ypix, - (t_floatarg)shift, (t_floatarg)0, (t_floatarg)alt); //fprintf(stderr,"atom click\n"); sys_vgui(".x%lx.c itemconfigure %s -fill %s\n", canvas, rtext_gettag(y), "$pd_colors(selection)"); + gatom_click((t_gatom *)x, (t_floatarg)xpix, (t_floatarg)ypix, + (t_floatarg)shift, (t_floatarg)0, (t_floatarg)alt); } return (1); } diff --git a/pd/src/x_gui.c b/pd/src/x_gui.c index 4fa11894f..9cb78dec3 100644 --- a/pd/src/x_gui.c +++ b/pd/src/x_gui.c @@ -311,18 +311,28 @@ static void savepanel_setup(void) /* ---------------------- key and its relatives ------------------ */ static t_symbol *key_sym, *keyup_sym, *keyname_sym; +static t_symbol *key_sym_a, *keyup_sym_a, *keyname_sym_a; static t_class *key_class, *keyup_class, *keyname_class; typedef struct _key { t_object x_obj; + t_symbol *x_keysym; } t_key; -static void *key_new( void) +static void *key_new(t_symbol *s, int argc, t_atom *argv) { t_key *x = (t_key *)pd_new(key_class); outlet_new(&x->x_obj, &s_float); - pd_bind(&x->x_obj.ob_pd, key_sym); + if (argc > 0 && argv->a_type == A_FLOAT) + if (atom_getfloatarg(0, argc, argv) == 0) + x->x_keysym = key_sym; + else if (atom_getfloatarg(0, argc, argv) == 1) + x->x_keysym = key_sym_a; + + if (!x->x_keysym) + x->x_keysym = key_sym; + pd_bind(&x->x_obj.ob_pd, x->x_keysym); return (x); } @@ -333,19 +343,28 @@ static void key_float(t_key *x, t_floatarg f) static void key_free(t_key *x) { - pd_unbind(&x->x_obj.ob_pd, key_sym); + pd_unbind(&x->x_obj.ob_pd, x->x_keysym); } typedef struct _keyup { t_object x_obj; + t_symbol *x_keysym; } t_keyup; -static void *keyup_new( void) +static void *keyup_new(t_symbol *s, int argc, t_atom *argv) { t_keyup *x = (t_keyup *)pd_new(keyup_class); outlet_new(&x->x_obj, &s_float); - pd_bind(&x->x_obj.ob_pd, keyup_sym); + if (argc > 0 && argv->a_type == A_FLOAT) + if (atom_getfloatarg(0, argc, argv) == 0) + x->x_keysym = keyup_sym; + else if (atom_getfloatarg(0, argc, argv) == 1) + x->x_keysym = keyup_sym_a; + + if (!x->x_keysym) + x->x_keysym = keyup_sym; + pd_bind(&x->x_obj.ob_pd, x->x_keysym); return (x); } @@ -356,22 +375,31 @@ static void keyup_float(t_keyup *x, t_floatarg f) static void keyup_free(t_keyup *x) { - pd_unbind(&x->x_obj.ob_pd, keyup_sym); + pd_unbind(&x->x_obj.ob_pd, x->x_keysym); } typedef struct _keyname { t_object x_obj; + t_symbol *x_keysym; t_outlet *x_outlet1; t_outlet *x_outlet2; } t_keyname; -static void *keyname_new( void) +static void *keyname_new(t_symbol *s, int argc, t_atom *argv) { t_keyname *x = (t_keyname *)pd_new(keyname_class); x->x_outlet1 = outlet_new(&x->x_obj, &s_float); x->x_outlet2 = outlet_new(&x->x_obj, &s_symbol); - pd_bind(&x->x_obj.ob_pd, keyname_sym); + if (argc > 0 && argv->a_type == A_FLOAT) + if (atom_getfloatarg(0, argc, argv) == 0) + x->x_keysym = keyname_sym; + else if (atom_getfloatarg(0, argc, argv) == 1) + x->x_keysym = keyname_sym_a; + + if (!x->x_keysym) + x->x_keysym = keyname_sym; + pd_bind(&x->x_obj.ob_pd, x->x_keysym); return (x); } @@ -383,29 +411,32 @@ static void keyname_list(t_keyname *x, t_symbol *s, int ac, t_atom *av) static void keyname_free(t_keyname *x) { - pd_unbind(&x->x_obj.ob_pd, keyname_sym); + pd_unbind(&x->x_obj.ob_pd, x->x_keysym); } static void key_setup(void) { key_class = class_new(gensym("key"), (t_newmethod)key_new, (t_method)key_free, - sizeof(t_key), CLASS_NOINLET, 0); + sizeof(t_key), 0, A_GIMME, 0); class_addfloat(key_class, key_float); key_sym = gensym("#key"); + key_sym_a = gensym("#key_a"); keyup_class = class_new(gensym("keyup"), (t_newmethod)keyup_new, (t_method)keyup_free, - sizeof(t_keyup), CLASS_NOINLET, 0); + sizeof(t_keyup), 0, A_GIMME, 0); class_addfloat(keyup_class, keyup_float); keyup_sym = gensym("#keyup"); + keyup_sym_a = gensym("#keyup_a"); //class_sethelpsymbol(keyup_class, gensym("key")); keyname_class = class_new(gensym("keyname"), (t_newmethod)keyname_new, (t_method)keyname_free, - sizeof(t_keyname), CLASS_NOINLET, 0); + sizeof(t_keyname), 0, A_GIMME, 0); class_addlist(keyname_class, keyname_list); keyname_sym = gensym("#keyname"); + keyname_sym_a = gensym("#keyname_a"); //class_sethelpsymbol(keyname_class, gensym("key")); } -- GitLab