/* Copyright (c) 2003 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ /* FIXME use guiconnect */ #include #include "m_pd.h" #include "g_canvas.h" #include "hammer/gui.h" //#define HAMMERGUI_DEBUG static t_class *hammergui_class = 0; static t_hammergui *sink = 0; static t_symbol *ps__up; static t_symbol *ps__focus; static t_symbol *ps__vised; static void hammergui_anything(t_hammergui *snk, t_symbol *s, int ac, t_atom *av) { /* Dummy method, filtering out messages from gui to the masters. This is needed in order to keep Pd's message system happy in a ``gray period'' -- after last master is unbound, and before gui bindings are cleared. */ #ifdef HAMMERGUI_DEBUG startpost("%s", s->s_name); postatom(ac, av); endpost(); #endif } /* filtering out redundant "_up" messages */ static void hammergui__up(t_hammergui *snk, t_floatarg f) { #ifdef HAMMERGUI_DEBUG post("_up %g", f); #endif if ((int)f) { if (!snk->g_up) { snk->g_up = 1; if (snk->g_mouse->s_thing) { t_atom at; SETFLOAT(&at, 1); pd_typedmess(snk->g_mouse->s_thing, ps__up, 1, &at); } } } else { if (snk->g_up) { snk->g_up = 0; if (snk->g_mouse->s_thing) { t_atom at; SETFLOAT(&at, 0); pd_typedmess(snk->g_mouse->s_thing, ps__up, 1, &at); } } } } static void hammergui__focus(t_hammergui *snk, t_symbol *s, t_floatarg f) { #ifdef HAMMERGUI_DEBUG if (s) post("_focus %s %g", s->s_name, f); #endif if (snk->g_focus->s_thing) { t_atom at[2]; SETSYMBOL(&at[0], s); SETFLOAT(&at[1], f); pd_typedmess(snk->g_focus->s_thing, ps__focus, 2, at); } } static void hammergui__vised(t_hammergui *snk, t_symbol *s, t_floatarg f) { #ifdef HAMMERGUI_DEBUG if (s) post("_vised %s %g", s->s_name, f); #endif if (snk->g_vised->s_thing) { t_atom at[2]; SETSYMBOL(&at[0], s); SETFLOAT(&at[1], f); pd_typedmess(snk->g_vised->s_thing, ps__vised, 2, at); } #if 0 /* How to be notified about changes of button state, prior to gui objects in a canvas? LATER find a reliable way -- delete if failed */ sys_vgui("bindtags %s {hammertag %s Canvas . all}\n", s->s_name, s->s_name); #endif } static void hammergui_dobindmouse(t_hammergui *snk) { #if 0 /* How to be notified about changes of button state, prior to gui objects in a canvas? LATER find a reliable way -- delete if failed */ sys_vgui("bind hammertag <> {pd [concat %s _up 0 \\;]}\n", snk->g_gui->s_name); sys_vgui("bind hammertag <> {pd [concat %s _up 1 \\;]}\n", snk->g_gui->s_name); #endif sys_vgui("bind all <> {pd [concat %s _up 0 \\;]}\n", snk->g_gui->s_name); sys_vgui("bind all <> {pd [concat %s _up 1 \\;]}\n", snk->g_gui->s_name); } static void hammergui__remouse(t_hammergui *snk) { if (snk->g_mouse->s_thing) { /* if a new master was bound in a gray period, we need to restore gui bindings */ #if 1 post("rebinding mouse..."); #endif hammergui_dobindmouse(snk); } } static void hammergui_dobindfocus(t_hammergui *snk) { sys_vgui("bind Canvas <> \ {pd [concat %s _focus %%W 1 \\;]}\n", snk->g_gui->s_name); sys_vgui("bind Canvas <> \ {pd [concat %s _focus %%W 0 \\;]}\n", snk->g_gui->s_name); } static void hammergui__refocus(t_hammergui *snk) { if (snk->g_focus->s_thing) { /* if a new master was bound in a gray period, we need to restore gui bindings */ #if 1 post("rebinding focus..."); #endif hammergui_dobindfocus(snk); } } static void hammergui_dobindvised(t_hammergui *snk) { sys_vgui("bind Canvas <> \ {pd [concat %s _vised %%W 1 \\;]}\n", snk->g_gui->s_name); sys_vgui("bind Canvas <> \ {pd [concat %s _vised %%W 0 \\;]}\n", snk->g_gui->s_name); } static void hammergui__revised(t_hammergui *snk) { if (snk->g_vised->s_thing) { /* if a new master was bound in a gray period, we need to restore gui bindings */ #if 1 post("rebinding vised events..."); #endif hammergui_dobindvised(snk); } } static void hammergui_setup(void) { hammergui_class = class_new(gensym("_hammergui"), 0, 0, sizeof(t_hammergui), CLASS_PD | CLASS_NOINLET, 0); class_addanything(hammergui_class, hammergui_anything); class_addmethod(hammergui_class, (t_method)hammergui__remouse, gensym("_remouse"), 0); class_addmethod(hammergui_class, (t_method)hammergui__refocus, gensym("_refocus"), 0); class_addmethod(hammergui_class, (t_method)hammergui__revised, gensym("_revised"), 0); ps__up = gensym("_up"); class_addmethod(hammergui_class, (t_method)hammergui__up, ps__up, A_FLOAT, 0); ps__focus = gensym("_focus"); class_addmethod(hammergui_class, (t_method)hammergui__focus, ps__focus, A_SYMBOL, A_FLOAT, 0); ps__vised = gensym("_vised"); class_addmethod(hammergui_class, (t_method)hammergui__vised, ps__vised, A_SYMBOL, A_FLOAT, 0); sys_gui("proc hammergui_remouse {} {\n"); sys_gui(" bind all <> {}\n"); sys_gui(" bind all <> {}\n"); sys_gui(" pd [concat #hammergui _remouse \\;]\n"); sys_gui("}\n"); sys_gui("proc hammergui_mousexy {target} {\n"); sys_gui(" set x [winfo pointerx .]\n"); sys_gui(" set y [winfo pointery .]\n"); sys_gui(" pd [concat #hammermouse $target $x $y \\;]\n"); sys_gui("}\n"); /* visibility hack for msw, LATER rethink */ sys_gui("global hammergui_ispolling\n"); sys_gui("global hammergui_x\n"); sys_gui("global hammergui_y\n"); sys_gui("set hammergui_ispolling 0\n"); sys_gui("set hammergui_x 0\n"); sys_gui("set hammergui_y 0\n"); sys_gui("proc hammergui_poll {} {\n"); sys_gui(" global hammergui_ispolling\n"); sys_gui(" global hammergui_x\n"); sys_gui(" global hammergui_y\n"); sys_gui(" if {$hammergui_ispolling == 1} {\n"); sys_gui(" set x [winfo pointerx .]\n"); sys_gui(" set y [winfo pointery .]\n"); sys_gui(" if {$hammergui_x != $x || $hammergui_y != $y} {\n"); sys_gui(" pd [concat #hammermouse _poll $x $y \\;]\n"); sys_gui(" set hammergui_x $x\n"); sys_gui(" set hammergui_y $y\n"); sys_gui(" }\n"); sys_gui(" after 50 hammergui_poll\n"); sys_gui(" }\n"); sys_gui("}\n"); sys_gui("proc hammergui_refocus {} {\n"); sys_gui(" bind Canvas <> {}\n"); sys_gui(" bind Canvas <> {}\n"); sys_gui(" pd [concat #hammergui _refocus \\;]\n"); sys_gui("}\n"); sys_gui("proc hammergui_revised {} {\n"); sys_gui(" bind Canvas <> {}\n"); sys_gui(" bind Canvas <> {}\n"); sys_gui(" pd [concat #hammergui _revised \\;]\n"); sys_gui("}\n"); } static int hammergui_validate(int dosetup) { if (dosetup) { if (!hammergui_class) hammergui_setup(); if (!sink) { sink = (t_hammergui *)pd_new(hammergui_class); sink->g_gui = gensym("#hammergui"); pd_bind((t_pd *)sink, sink->g_gui); } } if (hammergui_class && sink) return (1); else { bug("hammergui_validate"); return (0); } } static int hammergui_mousevalidate(int dosetup) { if (dosetup && !sink->g_mouse) { sink->g_mouse = gensym("#hammermouse"); sys_gui("event add <> \n"); sys_gui("event add <> \n"); } if (sink->g_mouse) return (1); else { bug("hammergui_mousevalidate"); return (0); } } static int hammergui_pollvalidate(int dosetup) { if (dosetup && !sink->g_poll) { sink->g_poll = gensym("#hammerpoll"); pd_bind((t_pd *)sink, sink->g_poll); /* never unbound */ } if (sink->g_poll) return (1); else { bug("hammergui_pollvalidate"); return (0); } } static int hammergui_focusvalidate(int dosetup) { if (dosetup && !sink->g_focus) { sink->g_focus = gensym("#hammerfocus"); sys_gui("event add <> \n"); sys_gui("event add <> \n"); } if (sink->g_focus) return (1); else { bug("hammergui_focusvalidate"); return (0); } } static int hammergui_visedvalidate(int dosetup) { if (dosetup && !sink->g_vised) { sink->g_vised = gensym("#hammervised"); /* subsequent map events have to be filtered out at the caller's side, LATER investigate */ sys_gui("event add <> \n"); sys_gui("event add <> \n"); } if (sink->g_vised) return (1); else { bug("hammergui_visedvalidate"); return (0); } } void hammergui_bindmouse(t_pd *master) { hammergui_validate(1); hammergui_mousevalidate(1); if (!sink->g_mouse->s_thing) hammergui_dobindmouse(sink); pd_bind(master, sink->g_mouse); } void hammergui_unbindmouse(t_pd *master) { if (hammergui_validate(0) && hammergui_mousevalidate(0) && sink->g_mouse->s_thing) { pd_unbind(master, sink->g_mouse); if (!sink->g_mouse->s_thing) sys_gui("hammergui_remouse\n"); } else bug("hammergui_unbindmouse"); } void hammergui_mousexy(t_symbol *s) { if (hammergui_validate(0)) sys_vgui("hammergui_mousexy %s\n", s->s_name); } void hammergui_willpoll(void) { hammergui_validate(1); hammergui_pollvalidate(1); } void hammergui_startpolling(t_pd *master) { if (hammergui_validate(0) && hammergui_pollvalidate(0)) { int doinit = (sink->g_poll->s_thing == (t_pd *)sink); pd_bind(master, sink->g_poll); if (doinit) { /* visibility hack for msw, LATER rethink */ sys_gui("global hammergui_ispolling\n"); sys_gui("set hammergui_ispolling 1\n"); sys_gui("hammergui_poll\n"); } } } void hammergui_stoppolling(t_pd *master) { if (hammergui_validate(0) && hammergui_pollvalidate(0)) { pd_unbind(master, sink->g_poll); if (sink->g_poll->s_thing == (t_pd *)sink) { sys_gui("after cancel hammergui_poll\n"); /* visibility hack for msw, LATER rethink */ sys_gui("global hammergui_ispolling\n"); sys_gui("set hammergui_ispolling 0\n"); } } } void hammergui_bindfocus(t_pd *master) { hammergui_validate(1); hammergui_focusvalidate(1); if (!sink->g_focus->s_thing) hammergui_dobindfocus(sink); pd_bind(master, sink->g_focus); } void hammergui_unbindfocus(t_pd *master) { if (hammergui_validate(0) && hammergui_focusvalidate(0) && sink->g_focus->s_thing) { pd_unbind(master, sink->g_focus); if (!sink->g_focus->s_thing) sys_gui("hammergui_refocus\n"); } else bug("hammergui_unbindfocus"); } void hammergui_bindvised(t_pd *master) { hammergui_validate(1); hammergui_visedvalidate(1); if (!sink->g_vised->s_thing) hammergui_dobindvised(sink); pd_bind(master, sink->g_vised); } void hammergui_unbindvised(t_pd *master) { if (hammergui_validate(0) && hammergui_visedvalidate(0) && sink->g_vised->s_thing) { pd_unbind(master, sink->g_vised); if (!sink->g_vised->s_thing) sys_gui("hammergui_revised\n"); } else bug("hammergui_unbindvised"); }