aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2003-07-20 02:36:32 +0000
committerThomas Grill <xovo@users.sourceforge.net>2003-07-20 02:36:32 +0000
commitcd0dbb399460d8c6e28a07c726bc914cfcda5ab3 (patch)
treea666f561be004b7e7b525870551a5631b46fb8b9
parentb24219e6ab0ce96f0d60f7a5f122c52b2c7e40aa (diff)
""
svn path=/trunk/; revision=779
-rw-r--r--externals/grill/flext/changes.txt1
-rw-r--r--externals/grill/flext/flext.vcproj3
-rw-r--r--externals/grill/flext/make-files.txt2
-rw-r--r--externals/grill/flext/source/flattr.cpp83
-rw-r--r--externals/grill/flext/source/flattr_ed.cpp380
-rw-r--r--externals/grill/flext/source/flclass.h62
-rw-r--r--externals/grill/flext/source/flext.cpp5
-rwxr-xr-xexternals/grill/flext/source/flprefix.h5
-rw-r--r--externals/grill/flext/source/flstdc.h13
-rw-r--r--externals/grill/flext/source/flsupport.h15
10 files changed, 497 insertions, 72 deletions
diff --git a/externals/grill/flext/changes.txt b/externals/grill/flext/changes.txt
index afcb2b2f..b23910b4 100644
--- a/externals/grill/flext/changes.txt
+++ b/externals/grill/flext/changes.txt
@@ -15,6 +15,7 @@ Version history:
0.5.0:
- added some more SIMD functions
+- PD attributes: added a TCL/TK editor dialog ("properties") and save attributes to patcher
- fixed wrong returned result of flext::buffer::set function
- fix for linux static exported function name-clash (individual linker namings for exported flext base classes)
- made message queue stuff global (static) for all flext objects
diff --git a/externals/grill/flext/flext.vcproj b/externals/grill/flext/flext.vcproj
index 61805158..4d1d349a 100644
--- a/externals/grill/flext/flext.vcproj
+++ b/externals/grill/flext/flext.vcproj
@@ -1203,6 +1203,9 @@
</FileConfiguration>
</File>
<File
+ RelativePath=".\source\flattr_ed.cpp">
+ </File>
+ <File
RelativePath="source\flbind.cpp">
<FileConfiguration
Name="Threads DLL Debug|Win32">
diff --git a/externals/grill/flext/make-files.txt b/externals/grill/flext/make-files.txt
index 02422580..90e7b27e 100644
--- a/externals/grill/flext/make-files.txt
+++ b/externals/grill/flext/make-files.txt
@@ -1,4 +1,4 @@
-SRCS=flbase.cpp flext.cpp flbuf.cpp fldsp.cpp fllib.cpp flxlet.cpp flattr.cpp flsupport.cpp \
+SRCS=flbase.cpp flext.cpp flbuf.cpp fldsp.cpp fllib.cpp flxlet.cpp flattr.cpp flattr_ed.cpp flsupport.cpp \
flutil.cpp flatom.cpp flatom_pr.cpp flthr.cpp fltimer.cpp flsimd.cpp flout.cpp \
flatom_app.cpp flatom_part.cpp flitem.cpp flmeth.cpp flmsg.cpp \
flproxy.cpp flqueue.cpp flbind.cpp
diff --git a/externals/grill/flext/source/flattr.cpp b/externals/grill/flext/source/flattr.cpp
index e22c15a8..660743f5 100644
--- a/externals/grill/flext/source/flattr.cpp
+++ b/externals/grill/flext/source/flattr.cpp
@@ -84,7 +84,7 @@ static int sortcmp(const void *a, const void *b)
return strcmp(flext::GetString(*(t_atom *)a),flext::GetString(*(t_atom *)b));
}
-int flext_base::ListAttr(AtomList &la) const
+int flext_base::ListAttrib(AtomList &la) const
{
int cnt = attrhead?attrhead->Count():0;
int ccnt = clattrhead?clattrhead->Count():0;
@@ -111,7 +111,7 @@ int flext_base::ListAttr(AtomList &la) const
return ix;
}
-int flext_base::ListMeth(AtomList &la,int inlet) const
+int flext_base::ListMethods(AtomList &la,int inlet) const
{
int cnt = methhead?methhead->Count():0;
int ccnt = clmethhead?clmethhead->Count():0;
@@ -156,7 +156,11 @@ bool flext_base::InitAttrib(int argc,const t_atom *argv)
if(IsString(argv[nxt]) && *GetString(argv[nxt]) == '@') break;
const t_symbol *tag = MakeSymbol(GetString(argv[cur])+1);
- SetAttrib(tag,nxt-cur-1,argv+cur+1);
+ attritem *attr = FindAttrib(tag,false,true);
+ if(attr) {
+ if(SetAttrib(attr,nxt-cur-1,argv+cur+1))
+ SetAttribSave(attr,true);
+ }
}
return true;
}
@@ -165,7 +169,7 @@ bool flext_base::ListAttrib() const
{
if(procattr) {
AtomList la;
- int c = ListAttr(la);
+ int c = ListAttrib(la);
ToOutAnything(GetOutAttr(),MakeSymbol("attributes"),c,la.Atoms());
return true;
}
@@ -177,7 +181,7 @@ bool flext_base::ListMethods(int inlet) const
{
if(procattr) {
AtomList la;
- int c = ListMeth(la,inlet);
+ int c = ListMethods(la,inlet);
ToOutAnything(GetOutAttr(),MakeSymbol("methods"),c,la.Atoms());
return true;
}
@@ -193,7 +197,7 @@ bool flext_base::cb_ListMethods(flext_base *c,int argc,const t_atom *argv)
return false;
}
-flext_base::attritem *flext_base::FindAttr(const t_symbol *tag,bool get) const
+flext_base::attritem *flext_base::FindAttrib(const t_symbol *tag,bool get,bool msg) const
{
// first search within object scope
attritem *a = (attritem *)attrhead->Find(tag);
@@ -204,19 +208,22 @@ flext_base::attritem *flext_base::FindAttr(const t_symbol *tag,bool get) const
a = (attritem *)clattrhead->Find(tag);
while(a && (a->tag != tag || a->inlet != 0 || (get?a->IsSet():a->IsGet()))) a = (attritem *)a->nxt;
}
+
+ if(!a && msg) {
+ // print a message
+ error("%s - %s: attribute not found",thisName(),GetString(tag));
+ }
return a;
}
bool flext_base::SetAttrib(const t_symbol *tag,int argc,const t_atom *argv)
{
// search for matching attribute
- attritem *a = FindAttr(tag,false);
+ attritem *a = FindAttrib(tag,false,true);
if(a)
return SetAttrib(a,argc,argv);
- else {
- error("%s - %s: attribute not found",thisName(),GetString(tag));
+ else
return true;
- }
}
bool flext_base::SetAttrib(attritem *a,int argc,const t_atom *argv)
@@ -264,52 +271,84 @@ bool flext_base::SetAttrib(attritem *a,int argc,const t_atom *argv)
return true;
}
-bool flext_base::GetAttrib(attritem *a)
+
+bool flext_base::GetAttrib(attritem *a,AtomList &la) const
{
+ bool ok = true;
// main attribute tag
if(a) {
if(a->fun) {
- AtomList la;
t_any any;
switch(a->argtp) {
case a_float: {
- ((methfun_1)a->fun)(this,any);
+ ((methfun_1)a->fun)(const_cast<flext_base *>(this),any);
la(1);
SetFloat(la[0],any.ft);
break;
}
case a_int: {
- ((methfun_1)a->fun)(this,any);
+ ((methfun_1)a->fun)(const_cast<flext_base *>(this),any);
la(1);
SetInt(la[0],any.it);
break;
}
case a_symbol: {
- ((methfun_1)a->fun)(this,any);
+ ((methfun_1)a->fun)(const_cast<flext_base *>(this),any);
la(1);
SetSymbol(la[0],any.st);
break;
}
case a_LIST: {
any.vt = &la;
- ((methfun_1)a->fun)(this,any);
+ ((methfun_1)a->fun)(const_cast<flext_base *>(this),any);
break;
}
default:
ERRINTERNAL();
+ ok = false;
}
- ToOutAnything(GetOutAttr(),a->tag,la.Count(),la.Atoms());
}
- else
- post("%s - attribute %s has no set method",thisName(),GetString(a->tag));
+ else {
+ post("%s - attribute %s has no get method",thisName(),GetString(a->tag));
+ ok = false;
+ }
}
- else
+ else {
error("%s - %s: attribute not found",thisName(),GetString(a->tag));
- return true;
+ ok = false;
+ }
+ return ok;
+}
+
+bool flext_base::GetAttrib(attritem *a)
+{
+ AtomList la;
+ bool ret = GetAttrib(a,la);
+ if(ret) ToOutAnything(GetOutAttr(),a->tag,la.Count(),la.Atoms());
+ return ret;
+}
+
+bool flext_base::GetAttrib(const t_symbol *s,AtomList &a) const
+{
+ attritem *attr = FindAttrib(s,true);
+ return attr && GetAttrib(attr,a);
}
+
bool flext_base::DumpAttrib(const t_symbol *attr) const
{
- attritem *item = FindAttr(attr,true);
+ attritem *item = FindAttrib(attr,true);
return item && const_cast<flext_base *>(this)->GetAttrib(item);
}
+
+void flext_base::SetAttribSave(attritem *a,bool save)
+{
+ a->SetSave(save);
+ if(a->BothExist()) {
+ // find opposite attribute item
+ attritem *b = FindAttrib(a->tag,!a->IsGet());
+ FLEXT_ASSERT(b != NULL);
+
+ b->SetSave(save);
+ }
+}
diff --git a/externals/grill/flext/source/flattr_ed.cpp b/externals/grill/flext/source/flattr_ed.cpp
new file mode 100644
index 00000000..ec096ef5
--- /dev/null
+++ b/externals/grill/flext/source/flattr_ed.cpp
@@ -0,0 +1,380 @@
+/*
+
+flext - C++ layer for Max/MSP and pd (pure data) externals
+
+Copyright (c) 2001-2003 Thomas Grill (xovo@gmx.net)
+For information on usage and redistribution, and for a DISCLAIMER OF ALL
+WARRANTIES, see the file, "license.txt," in this distribution.
+
+*/
+
+/*! \file flattr_ed.cpp
+ \brief Attribute editor (property dialog) for PD
+*/
+
+#include "flprefix.h"
+
+#if FLEXT_SYS == FLEXT_SYS_PD && !defined(FLEXT_NOATTREDIT)
+
+#ifdef _MSC_VER
+#pragma warning( disable : 4091 )
+#endif
+
+#include <m_imp.h>
+#include "flext.h"
+
+#include <string.h>
+#include <stdio.h>
+
+#ifdef __MWERKS__
+#define STD std
+#else
+#define STD
+#endif
+
+
+#if !defined(PD_VERSION_MAJOR)
+ /* PD version 0.36 or below */
+
+ /* Call this to get a gobj's bounding rectangle in pixels */
+ typedef void (*t_getrectfn)(t_gobj *x, struct _glist *glist,
+ int *x1, int *y1, int *x2, int *y2);
+ /* and this to displace a gobj: */
+ typedef void (*t_displacefn)(t_gobj *x, struct _glist *glist, int dx, int dy);
+ /* change color to show selection: */
+ typedef void (*t_selectfn)(t_gobj *x, struct _glist *glist, int state);
+ /* change appearance to show activation/deactivation: */
+ typedef void (*t_activatefn)(t_gobj *x, struct _glist *glist, int state);
+ /* warn a gobj it's about to be deleted */
+ typedef void (*t_deletefn)(t_gobj *x, struct _glist *glist);
+ /* making visible or invisible */
+ typedef void (*t_visfn)(t_gobj *x, struct _glist *glist, int flag);
+ /* field a mouse click (when not in "edit" mode) */
+ typedef int (*t_clickfn)(t_gobj *x, struct _glist *glist,
+ int xpix, int ypix, int shift, int alt, int dbl, int doit);
+ /* save to a binbuf */
+ typedef void (*t_savefn)(t_gobj *x, t_binbuf *b);
+ /* open properties dialog */
+ typedef void (*t_propertiesfn)(t_gobj *x, struct _glist *glist);
+ /* ... and later, resizing; getting/setting font or color... */
+
+ struct _widgetbehavior
+ {
+ t_getrectfn w_getrectfn;
+ t_displacefn w_displacefn;
+ t_selectfn w_selectfn;
+ t_activatefn w_activatefn;
+ t_deletefn w_deletefn;
+ t_visfn w_visfn;
+ t_clickfn w_clickfn;
+ t_savefn w_savefn;
+ t_propertiesfn w_propertiesfn;
+ };
+
+#elif !defined(PD_VERSION_MINOR)
+ #error Flext cannot be compiled with this version!
+#else
+ #include <g_canvas.h>
+#endif
+
+
+static t_widgetbehavior widgetbehavior;
+static void (*ori_vis)(t_gobj *c, t_glist *, int vis) = NULL;
+
+void flext_base::SetAttrEditor(t_classid c)
+{
+ // widgetbehavior struct MUST be resident... (static is just ok here)
+
+ widgetbehavior.w_getrectfn = c->c_wb->w_getrectfn;
+ widgetbehavior.w_displacefn = c->c_wb->w_displacefn;
+ widgetbehavior.w_selectfn = c->c_wb->w_selectfn;
+ widgetbehavior.w_activatefn = c->c_wb->w_activatefn;
+ widgetbehavior.w_deletefn = c->c_wb->w_deletefn;
+ ori_vis = c->c_wb->w_visfn;
+ widgetbehavior.w_visfn = cb_GfxVis;
+ widgetbehavior.w_clickfn = c->c_wb->w_clickfn;
+ widgetbehavior.w_propertiesfn = cb_GfxProperties;
+ widgetbehavior.w_savefn = cb_GfxSave;
+ class_setwidget(c, &widgetbehavior);
+
+
+ // generate the script for the property dialog
+
+ sys_gui(
+ "proc flext_apply {id alen} {\n"
+ // strip "." from the TK id to make a variable name suffix
+ "set vid [string trimleft $id .]\n"
+
+ // make a list of the attribute values (including save flags)
+ "set lst {}\n"
+ "for {set ix 0} {$ix < $alen} {incr ix} {\n"
+ "set var_attr_name [concat [concat var_name_$ix]_$vid ]\n"
+ "global $var_attr_name\n"
+ "set var_attr_val [concat [concat var_val_$ix]_$vid ]\n"
+ "global $var_attr_val\n"
+ "set var_attr_save [concat [concat var_save_$ix]_$vid ]\n"
+ "global $var_attr_save\n"
+
+ "lappend lst [eval concat $$var_attr_name]\n"
+ // see if it's a list
+ "set len [llength [expr $$var_attr_val]]\n"
+ "if { $len > 1 } {\n"
+ "set lst [concat $lst \"list\" $len [expr $$var_attr_val]]\n"
+ "} else {\n"
+ "lappend lst [expr $$var_attr_val]\n"
+ "}\n"
+ "lappend lst [eval concat $$var_attr_save]\n"
+ "}\n"
+
+ "set cmd [concat $id attributedialog $lst \\;]\n"
+ // puts stderr $cmd
+ "pd $cmd\n"
+ "}\n"
+
+ "proc flext_cancel {id} {\n"
+ "set cmd [concat $id cancel \\;]\n"
+ // puts stderr $cmd
+ "pd $cmd\n"
+ "}\n"
+
+ "proc flext_ok {id alen} {\n"
+ "flext_apply $id $alen\n"
+ "flext_cancel $id\n"
+ "}\n"
+
+ "proc pdtk_flext_dialog {id attrlist} {\n"
+ "set vid [string trimleft $id .]\n"
+ "set alen [expr [llength $attrlist] / 3 ]\n"
+
+ "toplevel $id\n"
+ "wm title $id {object attributes}\n"
+ "wm protocol $id WM_DELETE_WINDOW [concat flext_cancel $id]\n"
+/*
+ "label $id.label -text {Attributes}\n"
+ "pack $id.label -side top\n"
+*/
+ "set ix 0\n"
+
+ "foreach {an av asv} $attrlist {\n"
+ "set nm [concat $id.nm-$ix]\n"
+
+ "set var_attr_name [concat [concat var_name_$ix]_$vid ]\n"
+ "global $var_attr_name\n"
+ "set $var_attr_name $an\n"
+
+ "set var_attr_val [concat [concat var_val_$ix]_$vid ]\n"
+ "global $var_attr_val\n"
+ "set $var_attr_val $av\n"
+
+ "set var_attr_save [concat [concat var_save_$ix]_$vid ]\n"
+ "global $var_attr_save\n"
+ "set $var_attr_save $asv\n"
+
+ "frame $nm\n"
+ "pack $nm -side top\n"
+ "label $nm.lwidth -text \"$an :\"\n"
+ "entry $nm.width -textvariable $var_attr_val -width 20\n"
+ "checkbutton $nm.save -text {save} -variable $var_attr_save -anchor w\n"
+ "pack $nm.lwidth $nm.width $nm.save -side left\n"
+ "bind $nm.width <KeyPress-Return> [concat flext_ok $id $alen]\n"
+
+ "incr ix\n"
+ "}\n"
+
+// "focus $id.1-rangef.width\n"
+
+
+ // Buttons
+
+ "frame $id.buttonframe\n"
+ "pack $id.buttonframe -side bottom -fill x -pady 2m\n"
+
+ "button $id.buttonframe.cancel -text {Cancel} -command \"flext_cancel $id\"\n"
+ "button $id.buttonframe.apply -text {Apply} -command \"flext_apply $id $alen\"\n"
+ "button $id.buttonframe.ok -text {OK} -command \"flext_ok $id $alen\"\n"
+
+ "pack $id.buttonframe.cancel -side left -expand 1\n"
+ "pack $id.buttonframe.apply -side left -expand 1\n"
+ "pack $id.buttonframe.ok -side left -expand 1\n"
+
+ "}\n"
+ );
+}
+
+
+void flext_base::cb_GfxProperties(t_gobj *c, t_glist *)
+{
+ flext_base *th = thisObject(c);
+ char buf[1000],*b = buf;
+
+ AtomList la;
+ int cnt = th->ListAttrib(la);
+
+ STD::sprintf(b, "pdtk_flext_dialog %%s { "); b += strlen(b);
+
+ for(int i = 0; i < cnt; ++i) {
+ STD::sprintf(b,"%s {",GetString(la[i])); b += strlen(b);
+
+ bool sv;
+
+ // get attribute
+ attritem *attr = th->FindAttrib(GetSymbol(la[i]),true);
+
+ if(attr) {
+ // Attribute is gettable
+
+ // Get attribute value
+ AtomList lv;
+ th->GetAttrib(attr,lv);
+
+ sv = th->GetAttribSave(attr);
+
+ for(int j = 0; j < lv.Count(); ++j) {
+ if(IsString(lv[j]))
+ STD::sprintf(b,"%s",GetString(lv[j]));
+ else if(IsFloat(lv[j]))
+ STD::sprintf(b,"%f",GetFloat(lv[j]));
+ else if(IsInt(lv[j]))
+ STD::sprintf(b,"%i",GetInt(lv[j]));
+ else
+ FLEXT_ASSERT(false);
+ b += strlen(b);
+
+ if(j < lv.Count()-1) *(b++) = ' ';
+ }
+ }
+ else {
+ // Attribute is not gettable
+ sv = false;
+
+ // \TODO set flag for tcl/tk dialog
+ }
+
+ STD::sprintf(b, "} %i ", sv?1:0); b += strlen(b);
+ }
+
+ strcpy(b, " }\n");
+
+ gfxstub_new((t_pd *)th->thisHdr(), th->thisHdr(), buf);
+}
+
+//! Strip the attributes off the object command line
+void flext_base::cb_GfxVis(t_gobj *c, t_glist *gl, int vis)
+{
+ flext_base *th = thisObject(c);
+ t_text *x = (t_text *)th->thisHdr();
+ FLEXT_ASSERT(x->te_binbuf);
+
+ int argc = binbuf_getnatom(x->te_binbuf);
+ t_atom *argv = binbuf_getvec(x->te_binbuf);
+ int cnt = CheckAttrib(argc,argv);
+
+ if(cnt) {
+ t_binbuf *nb = binbuf_new();
+ binbuf_restore(nb,cnt,argv);
+ binbuf_free(x->te_binbuf);
+ x->te_binbuf = nb;
+ }
+
+ ori_vis(c,gl,vis);
+}
+
+void flext_base::cb_GfxSave(t_gobj *c, t_binbuf *b)
+{
+ flext_base *th = thisObject(c);
+ t_text *t = (t_text *)c;
+ binbuf_addv(b, "ssiis", gensym("#X"),gensym("obj"), t->te_xpix, t->te_ypix,MakeSymbol(th->thisName()));
+
+ int argc = binbuf_getnatom(t->te_binbuf);
+ t_atom *argv = binbuf_getvec(t->te_binbuf);
+ int cnt = CheckAttrib(argc,argv);
+
+ // process the creation arguments
+ for(int i = 1; i < cnt; ++i) {
+ if(IsString(argv[i]))
+ binbuf_addv(b,"s",GetSymbol(argv[i]));
+ else if(IsFloat(argv[i]))
+ binbuf_addv(b,"f",GetFloat(argv[i]));
+ else if(IsInt(argv[i]))
+ binbuf_addv(b,"i",GetInt(argv[i]));
+ else
+ FLEXT_ASSERT(false);
+ }
+
+ // process the attributes
+ AtomList la;
+ cnt = th->ListAttrib(la);
+ char attrname[100];
+ *attrname= '@';
+
+ for(int i = 0; i < cnt; ++i) {
+ // must be both settable and gettable....
+ attritem *attr = th->FindAttrib(GetSymbol(la[i]),true);
+
+ if(attr && attr->BothExist() && th->GetAttribSave(attr)) {
+ // Get attribute value
+ AtomList lv;
+ th->GetAttrib(attr,lv);
+
+ strcpy(attrname+1,GetString(la[i]));
+ binbuf_addv(b,"s",MakeSymbol(attrname));
+
+ for(int j = 0; j < lv.Count(); ++j) {
+ if(IsString(lv[j]))
+ binbuf_addv(b,"s",GetSymbol(lv[j]));
+ else if(IsFloat(lv[j]))
+ binbuf_addv(b,"f",GetFloat(lv[j]));
+ else if(IsInt(lv[j]))
+ binbuf_addv(b,"i",GetInt(lv[j]));
+ else
+ FLEXT_ASSERT(false);
+ }
+ }
+ }
+
+ binbuf_addv(b, ";");
+}
+
+bool flext_base::cb_AttrDialog(flext_base *th,int argc,const t_atom *argv)
+{
+ int i = 0;
+ if(IsSymbol(argv[i]) && GetSymbol(argv[i]) == sym_list) ++i;
+
+ for(; i < argc; ) {
+ FLEXT_ASSERT(IsSymbol(argv[i]));
+
+ const t_symbol *aname = GetSymbol(argv[i]);
+ i++;
+
+ int cnt,offs;
+ if(IsSymbol(argv[i]) && GetSymbol(argv[i]) == sym_list) {
+ i++;
+ FLEXT_ASSERT(CanbeInt(argv[i]));
+ cnt = GetAInt(argv[i]);
+ offs = ++i;
+ }
+ else
+ offs = i,cnt = 1;
+
+ i += cnt;
+
+ FLEXT_ASSERT(i < argc);
+ bool sv = CanbeBool(argv[i]) && GetABool(argv[i]);
+ ++i;
+
+ // find settable attribute
+ attritem *attr = th->FindAttrib(aname,false);
+ if(attr) {
+ th->SetAttribSave(attr,sv);
+ bool ret = th->SetAttrib(attr,cnt,argv+offs);
+ FLEXT_ASSERT(ret);
+ }
+ else {
+ post("%s - Attribute %s can't be set",th->thisName(),GetString(aname));
+ }
+ }
+ return true;
+}
+
+
+#endif // FLEXT_SYS_PD
diff --git a/externals/grill/flext/source/flclass.h b/externals/grill/flext/source/flclass.h
index 6b361cc7..6536590f 100644
--- a/externals/grill/flext/source/flclass.h
+++ b/externals/grill/flext/source/flclass.h
@@ -527,9 +527,19 @@ protected:
//! Dump an attribute to the attribute outlet
bool DumpAttrib(const char *attr) const { return DumpAttrib(MakeSymbol(attr)); }
- /*! \addtogroup FLEXT_C_INOUT
+ //! List attributes
+ int ListAttrib(AtomList &a) const;
+ //! Get an attribute value
+ bool GetAttrib(const t_symbol *s,AtomList &a) const;
+ //! Set an attribute value
+ bool SetAttrib(const t_symbol *s,const AtomList &a) { return SetAttrib(s,a.Count(),a.Atoms()); }
+
+ //! List methods
+ int ListMethods(AtomList &a,int inlet = 0) const;
+
+/*! \addtogroup FLEXT_C_INOUT
@{
- */
+*/
//! \brief get a code for a list of inlets or outlets
unsigned long XletCode(xlet::type tp = xlet::tp_none,...); // end list with 0 (= tp_none) !!
@@ -558,6 +568,7 @@ protected:
//! @} FLEXT_C_INOUT
+
// method handling
public:
@@ -641,6 +652,8 @@ protected:
bool IsGet() const { return (flags&afl_getset) == afl_get; }
bool IsSet() const { return (flags&afl_getset) == afl_set; }
bool BothExist() const { return (flags&afl_bothexist) != 0; }
+ void SetSave(bool s) { if(s) flags |= afl_save; else flags &= ~afl_save; }
+ bool IsSaved() const { return (flags&afl_save) != 0; }
int flags;
metharg argtp;
@@ -732,9 +745,7 @@ private:
itemarr *attrhead,*clattrhead;
- attritem *FindAttr(const t_symbol *tag,bool get) const;
- int ListAttr(AtomList &a) const;
- int ListMeth(AtomList &a,int inlet = 0) const;
+ attritem *FindAttrib(const t_symbol *tag,bool get,bool msg = false) const;
static int CheckAttrib(int argc,const t_atom *argv);
bool InitAttrib(int argc,const t_atom *argv);
@@ -742,47 +753,36 @@ private:
bool ListMethods(int inlet = 0) const;
bool ListAttrib() const;
bool GetAttrib(attritem *a);
+ bool GetAttrib(attritem *a,AtomList &l) const;
bool SetAttrib(const t_symbol *s,int argc,const t_atom *argv);
bool SetAttrib(attritem *a,int argc,const t_atom *argv);
+ void SetAttribSave(attritem *a,bool save);
+ bool GetAttribSave(attritem *a) const { return a->IsSaved(); }
+
static bool cb_ListMethods(flext_base *c,int argc,const t_atom *argv);
static bool cb_ListAttrib(flext_base *c) { return c->ListAttrib(); }
// queue stuff
-// class qmsg;
-// static qmsg *qhead,*qtail;
-
+ //! Start message queue
+ static void StartQueue();
//! Flush messages in the queue
static void QFlush(flext_base *th = NULL);
- //! Queue worker function
-// static void QWork(bool qlock,bool syslock);
+#if FLEXT_SYS == FLEXT_SYS_PD
- //! Start message queue
- static void StartQueue();
-#if FLEXT_SYS == FLEXT_SYS_JMAX
-// static void QTick(int winlet = 0, fts_symbol_t s = NULL, int ac = 0, const fts_atom_t *at = NULL);
-#else // PD or Max
-// static void QTick();
-#ifndef FLEXT_QTHR
-// static t_qelem *qclk;
-#else
- //! Queue worker thread function
-// static void *QWorker(void *);
- //! Queue worker thread conditional
-// static ThrCond qthrcond;
-#endif
-#endif
+#if !defined(FLEXT_NOATTREDIT)
+ // attribute editor
+ static void SetAttrEditor(t_classid c);
-// static void Queue(qmsg *m);
-#ifdef FLEXT_THREADS
-// static ThrMutex qmutex;
+ static bool cb_AttrDialog(flext_base *c,int argc,const t_atom *argv);
+ static void cb_GfxProperties(t_gobj *c, t_glist *);
+ static void cb_GfxVis(t_gobj *c, t_glist *gl, int vis);
+ static void cb_GfxSave(t_gobj *c, t_binbuf *b);
#endif
-
-#if FLEXT_SYS == FLEXT_SYS_PD
- // proxy object (for additional inlets) stuff
+ // proxy object (for additional inlets)
static t_class *px_class;
struct px_object // no virtual table!
diff --git a/externals/grill/flext/source/flext.cpp b/externals/grill/flext/source/flext.cpp
index ce35e205..b75e5472 100644
--- a/externals/grill/flext/source/flext.cpp
+++ b/externals/grill/flext/source/flext.cpp
@@ -157,6 +157,11 @@ void flext_base::Setup(t_classid id)
if(process_attributes) {
AddMethod(id,0,"getattributes",cb_ListAttrib);
AddMethod(id,0,"getmethods",cb_ListMethods);
+
+#if FLEXT_SYS == FLEXT_SYS_PD && !defined(FLEXT_NOATTREDIT)
+ AddMethod(id,0,"attributedialog",cb_AttrDialog);
+ SetAttrEditor(id);
+#endif
}
SetProxies(c);
diff --git a/externals/grill/flext/source/flprefix.h b/externals/grill/flext/source/flprefix.h
index 4d34a975..7ab517df 100755
--- a/externals/grill/flext/source/flprefix.h
+++ b/externals/grill/flext/source/flprefix.h
@@ -358,6 +358,11 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#endif
// ----- macros for class names -----
+/*
+ With linux (flat linker namespace) and more than one flext-based external loaded all calls to static
+ exported functions refer to the first instance loaded!
+ Therefore different class names are used so that the correct type of flext function is called.
+*/
#if defined(FLEXT_SHARED)
#define FLEXT_CLASSDEF(CL) CL##_shared
#elif defined(FLEXT_THREADS)
diff --git a/externals/grill/flext/source/flstdc.h b/externals/grill/flext/source/flstdc.h
index c875ac1e..e45da76a 100644
--- a/externals/grill/flext/source/flstdc.h
+++ b/externals/grill/flext/source/flstdc.h
@@ -39,14 +39,21 @@ extern "C" {
/* PD header file structure has changed with version 0.37
from then on m_imp.h needs m_pd.h to be included before
on the other hand versions < 0.37 don't like that....
- (they want m_imp.h solely)
+ (they want m_imp.h solely as m_pd.h is included therein)
So better use the m_pd.h here also for the debug version.
Change that if really needed for debugging PD internals...
*/
- #include <m_pd.h>
+
+ #ifndef PD_VERSION
+ // include only if not already included
+ #include <m_pd.h>
+ #endif
// #include <m_imp.h> // for easier debugging
#else
- #include <m_pd.h> // for easier debugging
+ #ifndef PD_VERSION
+ // include only if not already included
+ #include <m_pd.h>
+ #endif
#endif
}
diff --git a/externals/grill/flext/source/flsupport.h b/externals/grill/flext/source/flsupport.h
index 789e6921..5c222205 100644
--- a/externals/grill/flext/source/flsupport.h
+++ b/externals/grill/flext/source/flsupport.h
@@ -988,21 +988,6 @@ protected:
friend class flext_obj;
#endif
-/*
- With linux and more than one flext-based external loaded all calls to static
- exported functions refer to the first instance loaded!
- As single- and multi-threaded to different initializations the function names have
- to be different as well.
-*/
-
-/*
-#ifdef FLEXT_THREADS
-#define FLEXT_SETUPFUNC SetupMulti
-#else
-#define FLEXT_SETUPFUNC SetupSingle
-#endif
- static void FLEXT_SETUPFUNC();
-*/
static void Setup();
static bool chktilde(const char *objname);