aboutsummaryrefslogtreecommitdiff
path: root/shared/hammer/gui.c
diff options
context:
space:
mode:
Diffstat (limited to 'shared/hammer/gui.c')
-rw-r--r--shared/hammer/gui.c438
1 files changed, 438 insertions, 0 deletions
diff --git a/shared/hammer/gui.c b/shared/hammer/gui.c
new file mode 100644
index 0000000..5e98ff8
--- /dev/null
+++ b/shared/hammer/gui.c
@@ -0,0 +1,438 @@
+/* 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 <stdio.h>
+#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 <<hammerdown>> {pd [concat %s _up 0 \\;]}\n",
+ snk->g_gui->s_name);
+ sys_vgui("bind hammertag <<hammerup>> {pd [concat %s _up 1 \\;]}\n",
+ snk->g_gui->s_name);
+#endif
+ sys_vgui("bind all <<hammerdown>> {pd [concat %s _up 0 \\;]}\n",
+ snk->g_gui->s_name);
+ sys_vgui("bind all <<hammerup>> {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 <<hammerfocusin>> \
+ {pd [concat %s _focus %%W 1 \\;]}\n", snk->g_gui->s_name);
+ sys_vgui("bind Canvas <<hammerfocusout>> \
+ {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 <<hammervised>> \
+ {pd [concat %s _vised %%W 1 \\;]}\n", snk->g_gui->s_name);
+ sys_vgui("bind Canvas <<hammerunvised>> \
+ {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 <<hammerdown>> {}\n");
+ sys_gui(" bind all <<hammerup>> {}\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 <<hammerfocusin>> {}\n");
+ sys_gui(" bind Canvas <<hammerfocusout>> {}\n");
+ sys_gui(" pd [concat #hammergui _refocus \\;]\n");
+ sys_gui("}\n");
+
+ sys_gui("proc hammergui_revised {} {\n");
+ sys_gui(" bind Canvas <<hammervised>> {}\n");
+ sys_gui(" bind Canvas <<hammerunvised>> {}\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 <<hammerdown>> <ButtonPress>\n");
+ sys_gui("event add <<hammerup>> <ButtonRelease>\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 <<hammerfocusin>> <FocusIn>\n");
+ sys_gui("event add <<hammerfocusout>> <FocusOut>\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 <<hammervised>> <Map>\n");
+ sys_gui("event add <<hammerunvised>> <Destroy>\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");
+}