From dcc4875679394abbb0d63d00a86375e7616915e3 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Sun, 12 Apr 2009 04:02:08 +0000 Subject: - made a single "proc_test" function to test if any of the cursor procs exist before trying to create them - now get the 'motion' data using [winfo pointerxy .] and a t_clock for polling. There should probably be a separate proc for polling that only sends the values if they have changed, while the bang method should always send them. - implemented button and mousewheel grabbing svn path=/trunk/externals/hcs/; revision=11012 --- cursor.c | 147 ++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 89 insertions(+), 58 deletions(-) (limited to 'cursor.c') diff --git a/cursor.c b/cursor.c index 93cc5c1..4a311d1 100644 --- a/cursor.c +++ b/cursor.c @@ -7,8 +7,10 @@ pd.tk, or cursor reset method could be done in help patch */ #include #include +#define POLLTIME 10 + static t_symbol *button_symbol; -static t_symbol *wheel_symbol; +static t_symbol *mousewheel_symbol; static t_symbol *motion_symbol; static t_symbol *x_symbol; static t_symbol *y_symbol; @@ -22,26 +24,51 @@ static t_class *cursor_class; typedef struct _cursor { t_object x_obj; + t_int am_polling; + t_clock *x_clock; t_symbol *receive_symbol; t_canvas *parent_canvas; t_outlet *data_outlet; // t_outlet *status_outlet; // not used (yet?) - t_int optionc; - char *optionv[]; } t_cursor; -/* idea from #tcl for a Tcl unbind */ +static void create_namespace(void) +{ + sys_gui("if { [namespace exists ::hcs_cursor_class]} {\n"); + sys_gui(" puts stderr {WARNING: ::hcs_cursor_class namespace exists!}\n"); + sys_gui("} else {\n"); + sys_gui(" namespace eval ::hcs_cursor_class {\n"); + sys_gui(" variable last_x 0\n"); + sys_gui(" variable last_y 0\n"); + sys_gui(" }\n"); + sys_gui("}\n"); +} +static void create_proc_test(void) +{ + sys_gui ("if {[info commands ::hcs_cursor_class::proc_test] eq {::hcs_cursor_class::proc_test}} {"); + sys_gui(" puts stderr {WARNING: ::hcs_cursor_class::proc_test exists!}\n"); + sys_gui("} else {\n"); + sys_gui(" proc ::hcs_cursor_class::proc_test {proc_name} {\n"); + sys_gui(" if {[info commands ::hcs_cursor_class::$proc_name] eq $proc_name} {\n"); + sys_gui(" puts stderr {WARNING: ::hcs_cursor_class::$proc_name exists!}\n"); + sys_gui(" return 1\n"); + sys_gui(" } else {\n"); + sys_gui(" return 0\n"); + sys_gui(" }\n"); + sys_gui(" }\n"); + sys_gui("}\n"); +} + +/* idea from #tcl for a Tcl unbind */ static void create_unbind (void) { - sys_gui("if { [info commands ::hcs_cursor_class::unbind] ne {::hcs_cursor_class::unbind}} {"); - sys_gui(" puts stderr {creating ::hcs_cursor_class::unbind}\n"); + sys_gui("if { ! [::hcs_cursor_class::proc_test unbind]} {"); sys_gui(" proc ::hcs_cursor_class::unbind {tag event script} {\n"); sys_gui(" set bind {}\n"); sys_gui(" foreach x [split [bind $tag $event] \"\n\"] {\n"); sys_gui(" if {$x != $script} {\n"); sys_gui(" lappend bind $x\n"); - sys_gui(" puts stderr {rebind $x $script}\n"); sys_gui(" }\n"); sys_gui(" }\n"); sys_gui(" bind $tag $event {}\n"); @@ -50,43 +77,38 @@ static void create_unbind (void) sys_gui("}\n"); } -static void create_namespace(void) -{ - sys_gui("if { [namespace exists ::hcs_cursor_class]} {\n"); - sys_gui(" puts stderr {WARNING: ::hcs_cursor_class namespace exists!}\n"); - sys_gui("} else {\n"); - sys_gui(" namespace eval ::hcs_cursor_class {\n"); - sys_gui(" variable send_to_pd 0\n"); - sys_gui(" variable last_x 0\n"); - sys_gui(" variable last_y 0\n"); - sys_gui(" }\n"); - sys_gui("}\n"); -} - static void create_button_proc(void) { + sys_gui ("if { ! [::hcs_cursor_class::proc_test button]} {"); + sys_gui (" proc ::hcs_cursor_class::button {button state} {\n"); + sys_vgui(" pd [concat %s button $button $state \\;]\n", + cursor_receive_symbol->s_name); + sys_gui (" }\n"); + sys_gui ("}\n"); } static void create_mousewheel_proc(void) { + sys_gui ("if { ! [::hcs_cursor_class::proc_test mousewheel]} {"); + sys_gui (" proc ::hcs_cursor_class::mousewheel {delta} {\n"); + sys_vgui(" pd [concat %s mousewheel $delta \\;]\n", + cursor_receive_symbol->s_name); + sys_gui (" }\n"); + sys_gui ("}\n"); } static void create_motion_proc(void) { /* create proc and bind it, if it doesn't exist */ - sys_gui("if {[info commands ::hcs_cursor_class::motion] ne {::hcs_cursor_class::motion}} {"); - sys_gui (" puts stderr {creating ::hcs_cursor_class::motion}\n"); + sys_gui("if { ![::hcs_cursor_class::proc_test motion]} {\n"); sys_gui (" proc ::hcs_cursor_class::motion {x y} {\n"); -// sys_gui (" if {{$::hcs_cursor_class::send_to_pd > 0} {\n"); // sys_gui (" if { $x != $::hcs_cursor_class::last_x \\\n"); // sys_gui (" || $y != $::hcs_cursor_class::last_y} {\n"); sys_vgui(" pd [concat %s motion $x $y \\;]\n", cursor_receive_symbol->s_name); // sys_gui (" }\n"); -// sys_gui (" }\n"); sys_gui (" }\n"); sys_gui ("}\n"); - sys_gui ("\n"); } static void cursor_setmethod(t_cursor *x, t_symbol *s, int argc, t_atom *argv) @@ -97,35 +119,44 @@ static void cursor_setmethod(t_cursor *x, t_symbol *s, int argc, t_atom *argv) static void cursor_bang(t_cursor *x) { - sys_vgui("pd [concat %s motion [winfo pointerx .] [winfo pointery .] \\;]\n", + sys_vgui("pd [concat %s motion [winfo pointerxy .] \\;]\n", x->receive_symbol->s_name); + if(x->am_polling) + clock_delay(x->x_clock, POLLTIME); } static void cursor_float(t_cursor *x, t_float f) { - if(f > 0) - { + if(f == 0) { + // TODO unbind from the global cursor receive symbol + pd_unbind(&x->x_obj.ob_pd, cursor_receive_symbol); + if (x->am_polling) + cursor_instances_polling--; + x->am_polling = 0; + clock_unset(x->x_clock); + /* if no more objects are listening, stop sending the events */ + post("subtract cursor_instances_polling %d", cursor_instances_polling); + if (cursor_instances_polling == 0) { + sys_gui("::hcs_cursor_class::unbind all {::hcs_cursor_class::button %b 1}\n"); + sys_gui("::hcs_cursor_class::unbind all {::hcs_cursor_class::button %b 0}\n"); + sys_gui("::hcs_cursor_class::unbind all {::hcs_cursor_class::mousewheel %D}\n"); +// sys_gui("::hcs_cursor_class::unbind all {::hcs_cursor_class::motion %x %y}\n"); + } + } else { // TODO make sure the procs are setup // TODO bind to the global cursor receive symbol pd_bind(&x->x_obj.ob_pd, cursor_receive_symbol); - cursor_instances_polling++; + if ( ! x->am_polling) + cursor_instances_polling++; + x->am_polling = 1; + clock_delay(x->x_clock, POLLTIME); /* if this is the first instance to start polling, set up the bind */ - post("cursor_instances_polling %d", cursor_instances_polling); + post("add cursor_instances_polling %d", cursor_instances_polling); if (cursor_instances_polling == 1) { - post("bind all "); - sys_gui ("bind all {+::hcs_cursor_class::motion %x %y}\n"); - } - } - else - { - // TODO unbind from the global cursor receive symbol - pd_unbind(&x->x_obj.ob_pd, cursor_receive_symbol); - cursor_instances_polling--; - /* if no more objects are listening, stop sending the events */ - post("cursor_instances_polling %d", cursor_instances_polling); - if (cursor_instances_polling == 0) { - post("unbind all "); - sys_gui ("::hcs_cursor_class::unbind all {::hcs_cursor_class::motion %x %y}\n"); + sys_gui("bind all {+::hcs_cursor_class::button %b 1}\n"); + sys_gui("bind all {+::hcs_cursor_class::button %b 0}\n"); + sys_gui("bind all {+::hcs_cursor_class::mousewheel %D}\n"); +// sys_gui("bind all {+::hcs_cursor_class::motion %x %y}\n"); } } } @@ -151,12 +182,12 @@ static void cursor_motion_callback(t_cursor *x, t_float x_position, t_float y_po outlet_anything(x->data_outlet, motion_symbol, 2, output_atoms); } -static void cursor_wheel_callback(t_cursor *x, t_float f) +static void cursor_mousewheel_callback(t_cursor *x, t_float f) { t_atom output_atom; SETFLOAT(&output_atom, f); - outlet_anything(x->data_outlet, wheel_symbol, 1, &output_atom); + outlet_anything(x->data_outlet, mousewheel_symbol, 1, &output_atom); } static void cursor_free(t_cursor *x) @@ -165,6 +196,7 @@ static void cursor_free(t_cursor *x) /* TODO free the "bind all" somehow so that the tcl procs aren't * continuing to work even tho no cursor objects are receiving the data */ cursor_instance_count--; + clock_free(x->x_clock); } static void *cursor_new(void) @@ -178,16 +210,11 @@ static void *cursor_new(void) x->receive_symbol = gensym(buf); pd_bind(&x->x_obj.ob_pd, x->receive_symbol); x->data_outlet = outlet_new(&x->x_obj, 0); -// x->status_outlet = outlet_new(&x->x_obj, 0); + //x->status_outlet = outlet_new(&x->x_obj, 0); -/* not working yet - sys_vgui("bind . {+pd [concat %s button %%b 1 \\;]}\n", - x->receive_symbol->s_name); - sys_vgui("bind . {+pd [concat %s button %%b 0 \\;]}\n", - x->receive_symbol->s_name); - sys_vgui("bind . {+pd [concat %s wheel %%D \\;]}\n", - x->receive_symbol->s_name); -*/ + x->am_polling = 0; + x->x_clock = clock_new(x, (t_method)cursor_bang); + cursor_instance_count++; return(x); @@ -203,18 +230,19 @@ void cursor_setup(void) class_addfloat(cursor_class, (t_method)cursor_float); button_symbol = gensym("button"); - wheel_symbol = gensym("wheel"); + mousewheel_symbol = gensym("mousewheel"); motion_symbol = gensym("motion"); x_symbol = gensym("x"); y_symbol = gensym("y"); + //status_symbol = gensym("status"); cursor_receive_symbol = gensym("#hcs_cursor_class_receive"); class_addmethod(cursor_class, (t_method)cursor_button_callback, button_symbol, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(cursor_class, (t_method)cursor_motion_callback, motion_symbol, A_DEFFLOAT, A_DEFFLOAT, 0); - class_addmethod(cursor_class, (t_method)cursor_wheel_callback, - wheel_symbol, A_DEFFLOAT, 0); + class_addmethod(cursor_class, (t_method)cursor_mousewheel_callback, + mousewheel_symbol, A_DEFFLOAT, 0); /* methods for setting the cursor icon */ class_addmethod(cursor_class, (t_method)cursor_setmethod, @@ -233,6 +261,9 @@ void cursor_setup(void) gensym("editmode_disconnect"), A_GIMME, 0); create_namespace(); + create_proc_test(); create_unbind(); create_motion_proc(); + create_mousewheel_proc(); + create_button_proc(); } -- cgit v1.2.1