aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/guitest/flgui.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'externals/grill/guitest/flgui.cpp')
-rw-r--r--externals/grill/guitest/flgui.cpp646
1 files changed, 646 insertions, 0 deletions
diff --git a/externals/grill/guitest/flgui.cpp b/externals/grill/guitest/flgui.cpp
new file mode 100644
index 00000000..86d8e4ea
--- /dev/null
+++ b/externals/grill/guitest/flgui.cpp
@@ -0,0 +1,646 @@
+#include "flgui.h"
+#include "flguiobj.h"
+#include "flinternal.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+
+#ifdef PD
+t_class *flext_gui::px_class = NULL;
+t_class *flext_gui::pxkey_class = NULL;
+
+struct flext_gui::px_object // no virtual table!
+{
+ t_object obj; // MUST reside at memory offset 0
+ t_canvas *canv;
+
+ void init(t_canvas *c) { canv = c; }
+};
+
+struct flext_gui::pxkey_object // no virtual table!
+{
+ t_object obj; // MUST reside at memory offset 0
+ flext_gui *th;
+
+ void init(flext_gui *t) { th = t; }
+};
+#endif
+
+
+flext_gui::flext_gui(int xs,int ys):
+ objs(NULL),
+#ifdef PD
+ xsize(xs),ysize(ys),
+#endif
+#ifdef MAXMSP
+ curx(-1),cury(-1),curmod(-1),
+ created(false),
+#endif
+ bindsym(NULL)
+{
+ canvas = new Canvas(thisCanvas());
+ objs = new GuiGroup(canvas);
+
+#ifdef PD
+ AddCanvas();
+#else
+ t_box *b = (t_box *)gensym("#B")->s_thing;
+
+ int x = b->b_rect.left,y = b->b_rect.top;
+ t_pxbox *p = thisHdr();
+ box_new(&p->z_box, thisCanvas(), F_DRAWFIRSTIN | F_GROWBOTH | F_SAVVY,x,y,x+xs,y+ys);
+ p->z_box.b_firstin = (void *)p; /* it's not really an inlet */
+ box_ready(&p->z_box);
+#endif
+}
+
+flext_gui::~flext_gui()
+{
+#ifdef PD
+ RmvCanvas();
+#endif
+
+ delete objs;
+ delete canvas;
+}
+
+
+void flext_gui::setup(t_class *c)
+{
+#ifdef PD
+ SetWidget(c);
+
+ pxkey_class = class_new(gensym("flext_gui key proxy"),NULL,NULL,sizeof(pxkey_object),CLASS_PD|CLASS_NOINLET, A_NULL);
+ add_anything(pxkey_class,pxkey_method);
+ pxkey = (pxkey_object *)pd_new(pxkey_class);
+
+ pd_bind(&pxkey_class,gensym("#keyname"));
+// pd_bind(&pxkey_class,gensym("#key"));
+// pd_bind(&pxkey_class,gensym("#keyup"));
+
+ gcanv = NULL;
+
+#ifdef DIRECT_TK
+ px_class = class_new(gensym("flext_gui proxy"),NULL,NULL,sizeof(px_object),CLASS_PD|CLASS_NOINLET, A_NULL);
+ add_anything(px_class,px_method);
+
+ gcm_motion = MakeSymbol("_tk_motion");
+ gcm_mousekey = MakeSymbol("_tk_mousekey");
+ gcm_mousewheel = MakeSymbol("_tk_mousewheel");
+ gcm_key = MakeSymbol("_tk_key");
+ gcm_destroy = MakeSymbol("_tk_destroy");
+#endif
+
+ // this is wrong if a modifier key is pressed during creation of the first object.....
+ curmod = 0;
+#else
+ addmess((method)sg_update, "update", A_CANT, A_NULL);
+ addmess((method)sg_click, "click", A_CANT, A_NULL);
+ addmess((method)sg_psave, "psave", A_CANT, A_NULL);
+ addmess((method)sg_bfont, "bfont", A_CANT, A_NULL);
+ addmess((method)sg_key, "key", A_CANT, A_NULL);
+ addmess((method)sg_bidle, "bidle", A_CANT, A_NULL);
+#endif
+}
+
+#ifdef PD
+
+int flext_gui::evmask = evMotion|evMouseDown|evKeyDown|evKeyUp;
+int flext_gui::curmod = 0;
+flext_gui::pxkey_object *flext_gui::pxkey = NULL;
+flext_gui::guicanv *flext_gui::gcanv = NULL;
+
+#ifdef DIRECT_TK
+const t_symbol *flext_gui::gcm_motion = NULL;
+const t_symbol *flext_gui::gcm_mousekey = NULL;
+const t_symbol *flext_gui::gcm_mousewheel = NULL;
+const t_symbol *flext_gui::gcm_key = NULL;
+const t_symbol *flext_gui::gcm_destroy = NULL;
+
+void flext_gui::px_method(px_object *obj,const t_symbol *s,int argc,t_atom *argv)
+{
+ guicanv *ix = gcanv;
+ for(; ix && ix->canv != obj->canv; ix = ix->nxt);
+
+ if(ix) {
+ CBParams parms;
+
+ if(s == gcm_motion) {
+ parms.kind = evMotion;
+ parms.pMotion.x = GetAInt(argv[0]);
+ parms.pMotion.y = GetAInt(argv[1]);
+ parms.pMotion.mod = GetAInt(argv[2]);
+ }
+ else if(s == gcm_mousekey) {
+ parms.kind = GetAInt(argv[0])?evMouseDown:evMouseUp;
+ parms.pMouseKey.x = GetAInt(argv[1]);
+ parms.pMouseKey.y = GetAInt(argv[2]);
+ parms.pMouseKey.b = GetAInt(argv[3]);
+ parms.pMouseKey.mod = GetAInt(argv[4]);
+ }
+ else if(s == gcm_mousewheel) {
+ parms.kind = evMouseWheel;
+ parms.pMouseWheel.x = GetAInt(argv[0]);
+ parms.pMouseWheel.y = GetAInt(argv[1]);
+ parms.pMouseWheel.mod = GetAInt(argv[2]);
+ parms.pMouseWheel.delta = GetAInt(argv[3]);
+ }
+ else if(s == gcm_key) {
+ parms.kind = GetAInt(argv[0])?evKeyDown:evKeyUp;
+ parms.pKey.k = GetAInt(argv[1]);
+ parms.pKey.a = GetAInt(argv[2]);
+// parms.pKey.n = GetAInt(argv[3]);
+ parms.pKey.mod = GetAInt(argv[4]);
+ }
+ else if(s == gcm_destroy) {
+// post("TK destroy");
+ DelCanvas(ix->canv);
+ }
+
+ if(parms.kind != evNone) {
+ for(canvobj *co = ix->head; co; co = co->nxt)
+ co->guiobj->m_Method(parms);
+ }
+
+ }
+ else
+ error("flext_gui: canvas not found!");
+}
+
+#endif
+
+static const char *extkeys[] = {
+ "Escape","F1","F2","F3","F4","F5","F6","F7","F8","F9","F10","F11","F12",
+ "Prior","Next","Home","End","Delete","Insert",""
+};
+
+void flext_gui::pxkey_method(pxkey_object *obj,const t_symbol *s,int argc,t_atom *argv)
+{
+/*
+ if(s == sym_float && argc == 1) {
+ lastkey = GetInt(argv[0]);
+ }
+ else
+*/
+ if(s == sym_list && argc == 2) {
+ CBParams p;
+
+ bool down = GetABool(argv[0]);
+ const char *str = GetString(argv[1]);
+ int code = str[0];
+ int asc = code;
+ int mod = mod_None;
+ if(code && str[1] != 0) {
+ code = asc = 0;
+ if(GetSymbol(argv[1]) == MakeSymbol("Shift_L") || GetSymbol(argv[1]) == MakeSymbol("Shift_R")) {
+ code = 2001;
+ mod = mod_Shift;
+ }
+ else if(GetSymbol(argv[1]) == MakeSymbol("Control_L") || GetSymbol(argv[1]) == MakeSymbol("Control_R")) {
+ code = 2002;
+ mod = mod_Ctrl;
+ }
+ else if(GetSymbol(argv[1]) == MakeSymbol("Alt_L") || GetSymbol(argv[1]) == MakeSymbol("Alt_R")) {
+ code = 2003;
+ mod = mod_Alt;
+ }
+ else {
+ for(int i = 0;; ++i) {
+ const char *ci = extkeys[i];
+ if(!*ci) break;
+ if(GetSymbol(argv[1]) == MakeSymbol(ci)) {
+ code = 1000+i;
+ break;
+ }
+ }
+ }
+#ifdef DEBUG
+ else
+ post("unknown modifier %s",str);
+#endif
+ }
+
+ if(down) curmod |= mod;
+ else curmod &= ~mod;
+
+// post("Key down=%i c=%c mod=%i",down?1:0,code,curmod);
+
+ if(code || mod) {
+ // button is pressed
+ p.kind = down?evKeyDown:evKeyUp;
+ p.ext = true;
+ p.pKey.k = code; //lastkey;
+ p.pKey.a = asc;
+ p.pKey.mod = curmod;
+
+ for(guicanv *ix = gcanv; ix; ix = ix->nxt)
+ for(canvobj *ci = ix->head; ci; ci = ci->nxt)
+ ci->guiobj->m_Method(p);
+ }
+ }
+ else
+ post("flext_gui key proxy - unknown method");
+}
+
+
+flext_gui::guicanv::guicanv(t_canvas *c):
+ canv(c),nxt(NULL),ref(0),
+ head(NULL),tail(NULL)
+{
+ char tmp[25];
+ sprintf(tmp,"FLCANV%x",c);
+ sym = MakeSymbol(tmp);
+
+#ifdef DIRECT_TK
+ // proxy for canvas messages
+ (px = (px_object *)pd_new(px_class))->init(c);
+#endif
+}
+
+flext_gui::guicanv::~guicanv()
+{
+#ifdef DIRECT_TK
+ if(px) pd_free(&px->obj.ob_pd);
+#endif
+}
+
+void flext_gui::guicanv::Push(flext_gui *o)
+{
+ canvobj *co = new canvobj(o);
+ if(tail) tail->nxt = co;
+ tail = co;
+ if(!head) head = tail;
+
+ ++ref;
+}
+
+void flext_gui::guicanv::Pop(flext_gui *o)
+{
+ canvobj *prv = NULL,*ix = head;
+ for(; ix && ix->guiobj != o; prv = ix,ix = ix->nxt);
+
+ if(ix) {
+ --ref;
+ if(prv) prv->nxt = ix->nxt;
+ else head = ix->nxt;
+ if(!ix->nxt) tail = prv;
+ }
+ else
+ error("flext_gui: object not found in canvas!");
+}
+
+
+void flext_gui::AddCanvas()
+{
+ t_canvas *c = thisCanvas();
+ guicanv *prv = NULL,*ix = gcanv;
+ for(; ix && ix->canv != c; prv = ix,ix = ix->nxt);
+
+ if(ix) {
+ ix->Push(this);
+ }
+ else {
+ guicanv *nc = new guicanv(c);
+ if(prv) prv->nxt = nc;
+ else gcanv = nc;
+
+ nc->Push(this);
+
+#ifdef DIRECT_TK
+ pd_bind(&nc->px->obj.ob_pd,(t_symbol *)nc->sym);
+
+/*
+ // initialize new canvas object
+ sys_vgui("bind .x%x.c <Motion> {pd %s %s %%x %%y %%s \\;}\n",c,GetString(nc->sym),GetString(gcm_motion));
+
+ sys_vgui("bind .x%x.c <ButtonPress> {pd %s %s 1 %%x %%y %%b %%s \\;}\n",c,GetString(nc->sym),GetString(gcm_mousekey));
+ sys_vgui("bind .x%x.c <ButtonRelease> {pd %s %s 0 %%x %%y %%b %%s \\;}\n",c,GetString(nc->sym),GetString(gcm_mousekey));
+ sys_vgui("bind .x%x.c <MouseWheel> {pd %s %s %%x %%y %%s %%D \\;}\n",c,GetString(nc->sym),GetString(gcm_mousewheel));
+ sys_vgui("bind .x%x.c <KeyPress> {pd %s %s 1 %%k %%A %%N %%s \\;}\n",c,GetString(nc->sym),GetString(gcm_key));
+ sys_vgui("bind .x%x.c <KeyRelease> {pd %s %s 0 %%k %%A %%N %%s \\;}\n",c,GetString(nc->sym),GetString(gcm_key));
+
+ // what happend to objects in subpatchers?
+ sys_vgui("bind .x%x.c <Destroy> {pd %s %s \\;}\n",c,GetString(nc->sym),GetString(gcm_destroy));
+
+ // sys_vgui("bind .x%x.c <Visibility> {pd %s %s %x %s \\;}\n",c,GetString(nc->sym),"_tk_visibility",this);
+*/
+#endif
+ }
+}
+
+void flext_gui::RmvCanvas()
+{
+ guicanv *ix = gcanv;
+ for(; ix && ix->canv != thisCanvas(); ix = ix->nxt);
+
+ if(ix) {
+ ix->Pop(this);
+ if(!ix->Refs()) DelCanvas(thisCanvas());
+ }
+ else {
+ error("flext_gui: Canvas not found!");
+ }
+}
+
+void flext_gui::DelCanvas(t_canvas *c)
+{
+ guicanv *prv = NULL,*ix = gcanv;
+ for(; ix && ix->canv != c; prv = ix,ix = ix->nxt);
+
+ if(ix) {
+#ifdef DIRECT_TK
+ pd_unbind(&ix->px->obj.ob_pd,(t_symbol *)ix->sym);
+#endif
+
+ if(prv) prv->nxt = ix->nxt;
+ else gcanv = ix->nxt;
+ }
+ else {
+ error("flext_gui: Canvas not found!");
+ }
+}
+
+static GuiObj *GetGuiObj(const t_atom &a)
+{
+ GuiObj *th = NULL;
+ sscanf(flext::GetString(a),"%x",&th);
+ return th;
+}
+
+void flext_gui::g_Displace(int dx, int dy)
+{
+// post("Displace");
+
+ XLo(XLo()+dx);
+ YLo(YLo()+dy);
+
+ Group().MoveRel(dx,dy);
+ FixLines();
+}
+
+void flext_gui::g_Delete()
+{
+ objs->Clear();
+ DelLines();
+}
+
+
+
+t_widgetbehavior flext_gui::widgetbehavior;
+
+void flext_gui::SetWidget(t_class *c)
+{
+ // widgetbehavior struct MUST be resident... (static is just ok here)
+
+ widgetbehavior.w_getrectfn = sg_getrect;
+ widgetbehavior.w_displacefn = sg_displace;
+ widgetbehavior.w_selectfn = sg_select;
+ widgetbehavior.w_activatefn = NULL; //sg_activate;
+ widgetbehavior.w_deletefn = sg_delete;
+ widgetbehavior.w_visfn = sg_vis;
+ widgetbehavior.w_clickfn = sg_click;
+ widgetbehavior.w_propertiesfn = sg_properties;
+ widgetbehavior.w_savefn = sg_save;
+ class_setwidget(c, &widgetbehavior);
+}
+
+void flext_gui::sg_getrect(t_gobj *c, t_glist *,int *xp1, int *yp1, int *xp2, int *yp2)
+{
+ flext_gui *th = thisObject(c);
+ /*th->g_GetRect(*xp1,*yp1,*xp2,*yp2);*/
+ *xp1 = th->XLo(),*yp1 = th->YLo(),*xp2 = th->XHi(),*yp2 = th->YHi();
+}
+
+void flext_gui::sg_displace(t_gobj *c, t_glist *, int dx, int dy)
+{
+ thisObject(c)->g_Displace(dx,dy);
+}
+
+void flext_gui::sg_select(t_gobj *c, t_glist *, int selected)
+{
+// post("Select");
+
+ flext_gui *th = thisObject(c);
+ th->g_Edit(th->selected = (selected != 0));
+}
+
+void flext_gui::sg_vis(t_gobj *c, t_glist *, int vis)
+{
+ post("Visible %i",vis);
+
+ if(vis) {
+ flext_gui *g = thisObject(c);
+ g->g_Create();
+ g->Group().MoveRel(g->XLo(),g->YLo());
+ g->FixLines();
+ }
+}
+
+int flext_gui::sg_click(t_gobj *c, t_glist *,int xpix, int ypix, int shift, int alt, int dbl, int doit)
+{
+ flext_gui *g = thisObject(c);
+ CBParams p;
+ int x = xpix-g->XLo();
+ int y = ypix-g->YLo();
+
+ // PD bug: shift isn't reported for idle mousing
+// int mod = (alt?mod_Alt:0)+(shift?mod_Shift:0)+(dbl?mod_Double:0);
+
+ if(doit) {
+ // button is pressed
+ p.kind = evMouseDown;
+ p.pMouseKey.x = x;
+ p.pMouseKey.y = y;
+ p.pMouseKey.b = 1;
+ p.pMouseKey.mod = curmod; //mod;
+ }
+ else {
+ // only mouse position change
+ p.kind = evMotion;
+ p.pMotion.x = x;
+ p.pMotion.y = y;
+ p.pMotion.mod = curmod; //mod;
+ }
+ g->m_Method(p);
+ return 1;
+}
+
+void flext_gui::sg_delete(t_gobj *c, t_glist *)
+{
+ thisObject(c)->g_Delete();
+}
+
+void flext_gui::sg_properties(t_gobj *c, t_glist *)
+{
+ thisObject(c)->g_Properties();
+}
+
+void flext_gui::sg_save(t_gobj *c, t_binbuf *b)
+{
+ thisObject(c)->g_Save(b);
+}
+
+/*
+bool flext_gui::sg_Key(flext_base *c,int argc,t_atom *argv)
+{
+ return true;
+}
+
+bool flext_gui::sg_KeyNum(flext_base *c,int &keynum)
+{
+ flext_gui *g = dynamic_cast<flext_gui *>(c);
+ post("KeyNum %i",keynum);
+ return true;
+}
+
+bool flext_gui::sg_KeyUp(flext_base *c,int &keynum)
+{
+ flext_gui *g = dynamic_cast<flext_gui *>(c);
+ post("KeyUp %i",keynum);
+ return true;
+}
+*/
+
+#else // MAXMSP
+
+int flext_gui::evmask = evMotion|evMouseDown|evKeyDown;
+
+static void dragfun()
+{
+}
+
+static void tmfun()
+{
+}
+
+void flext_gui::sg_click(t_object *x, Point pt, short m)
+{
+ flext_gui *g = thisObject(x);
+ CBParams p(evMouseDown);
+ p.pMouseKey.x = pt.h-g->XLo();
+ p.pMouseKey.y = pt.v-g->YLo();
+ p.pMouseKey.b = 0;
+ p.pMouseKey.mod = (m&256?mod_Meta:0)+(m&512?mod_Shift:0)+(m&1024?mod_Caps:0)+(m&2048?mod_Alt:0)+(m&4096?mod_Ctrl:0);
+ g->m_Method(p);
+}
+
+void flext_gui::sg_update(t_object *x)
+{
+ flext_gui *g = thisObject(x);
+ if(!g->created) { g->g_Create(); g->created = true; }
+
+ // draw elements
+ g->Update();
+}
+
+void flext_gui::sg_psave (t_object *x, t_binbuf *dest) { thisObject(x)->g_Save(dest); }
+
+void flext_gui::sg_bfont (t_object *x, short size, short font) {}
+
+void flext_gui::sg_key (t_object *x, short keyvalue)
+{
+ flext_gui *g = thisObject(x);
+
+ CBParams p(evKeyDown);
+ p.pKey.k = keyvalue;
+ p.pKey.a = 0;
+ p.pKey.mod = 0;
+ g->m_Method(p);
+}
+
+void flext_gui::sg_enter (t_object *x) {}
+
+void flext_gui::sg_clipregion (t_object *x, RgnHandle *rgn, short *result) {}
+
+void flext_gui::sg_bidle (t_object *x)
+{
+ flext_gui *g = thisObject(x);
+ Point pnt; GetMouse(&pnt);
+
+ CBParams p(evMotion);
+ p.pMotion.x = pnt.h-g->XLo();
+ p.pMotion.y = pnt.v-g->YLo();
+ p.pMotion.mod = 0;
+
+ if(p.pMotion.x != g->curx || p.pMotion.y != g->cury || p.pMotion.mod != g->curmod) {
+ g->m_Method(p);
+ g->curx = p.pMotion.x;
+ g->cury = p.pMotion.y;
+ g->curmod = p.pMotion.mod;
+ }
+}
+
+void flext_gui::g_Displace(int dx, int dy)
+{
+}
+
+void flext_gui::g_Delete()
+{
+ objs->Clear();
+}
+
+void flext_gui::Update()
+{
+ box_ready(&thisHdr()->z_box);
+
+ if(Group().Canv().Pre(XLo(),YLo()))
+ Group().Draw();
+ Group().Canv().Post();
+}
+
+#endif // PD / MAXMSP
+
+void flext_gui::m_Method(const CBParams &p)
+{
+/*
+ switch(p.kind) {
+ case evMotion: {
+ // if(!g->Selected() || mod)
+ post("Motion: x=%i y=%i m=%i",p.pMotion.x,p.pMotion.y,p.pMotion.mod);
+ break;
+ }
+ case evMouseDown: {
+ post("MouseDown: x=%i y=%i b=%i m=%i",p.pMouseKey.x,p.pMouseKey.y,p.pMouseKey.b,p.pMouseKey.mod);
+ break;
+ }
+ case evMouseUp: {
+ post("MouseUp: x=%i y=%i b=%i m=%i",p.pMouseKey.x,p.pMouseKey.y,p.pMouseKey.b,p.pMouseKey.mod);
+ break;
+ }
+ case evMouseWheel: {
+ post("Mousewheel: x=%i y=%i m=%i d=%i",p.pMouseWheel.x,p.pMouseWheel.y,p.pMouseWheel.mod,p.pMouseWheel.delta);
+ break;
+ }
+ case evKeyDown: {
+ post("KeyDown: k=%i a=%i m=%i",p.pKey.k,p.pKey.a,p.pKey.mod);
+ break;
+ }
+ case evKeyUp: {
+ post("KeyUp: k=%i a=%i m=%i",p.pKey.k,p.pKey.a,p.pKey.mod);
+ break;
+ }
+ }
+*/
+ if(!Selected() || p.kind != evMotion || p.kind != evMouseDown || p.kind != evMouseUp)
+ Group().Method(*this,p);
+ }
+
+bool flext_gui::BindEvent(GuiSingle &o,bool (*cb)(flext_gui &o,GuiSingle &obj,const CBParams &p),int evs)
+{
+ if((evs&EventMask()) == evs) {
+ o.AddEvent(evs,cb);
+ return true;
+ }
+ else
+ // not all requested events supported
+ return false;
+}
+
+void flext_gui::UnbindEvent(GuiSingle &o,bool (*cb)(flext_gui &o,GuiSingle &obj,const CBParams &p),int evs)
+{
+ o.RmvEvent(evs,cb);
+}
+
+