aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas O Fredericks <mrtof@users.sourceforge.net>2009-11-04 13:28:43 +0000
committerThomas O Fredericks <mrtof@users.sourceforge.net>2009-11-04 13:28:43 +0000
commit09f42b21764953749f83accbf01948bc4b318577 (patch)
tree8806cc7dbe0ad46e26e838ac26dfed680faa3c2b
parent501c33dc76bcc440d0bc30955c22874075c31645 (diff)
Added menubutton
svn path=/trunk/externals/tof/; revision=12722
-rw-r--r--abs/OSCToParam.pd17
-rw-r--r--help/OSCToParam-help.pd4
-rw-r--r--help/menubutton-help.pd63
-rw-r--r--src/Makefile2
-rw-r--r--src/menubutton.c477
-rw-r--r--src/menubutton_w.h372
-rw-r--r--src/paramGui.h3
7 files changed, 917 insertions, 21 deletions
diff --git a/abs/OSCToParam.pd b/abs/OSCToParam.pd
index 7434608..dacc583 100644
--- a/abs/OSCToParam.pd
+++ b/abs/OSCToParam.pd
@@ -1,19 +1,4 @@
#N canvas 332 238 604 420 10;
#X obj 88 46 oscx/dumpOSC \$1;
#X obj 89 286 maxlib/remote;
-#X obj 88 170 list prepend \$0;
-#X obj 88 199 zexy/makesymbol %s%s;
-#X obj 88 96 list split 1;
-#X obj 89 223 list append;
-#X obj 89 257 list trim;
-#X obj 175 120 loadbang;
-#X obj 175 144 tof/getdollarzero 100;
-#X connect 0 0 4 0;
-#X connect 2 0 3 0;
-#X connect 3 0 5 0;
-#X connect 4 0 2 0;
-#X connect 4 1 5 1;
-#X connect 5 0 6 0;
-#X connect 6 0 1 0;
-#X connect 7 0 8 0;
-#X connect 8 0 2 1;
+#X connect 0 0 1 0;
diff --git a/help/OSCToParam-help.pd b/help/OSCToParam-help.pd
index 104218a..7084eec 100644
--- a/help/OSCToParam-help.pd
+++ b/help/OSCToParam-help.pd
@@ -6,6 +6,6 @@
#X text -3 -54 description: forwards all incomming OSC messages to
matching params.;
#X text -3 -20 tags: routing param OSC;
-#X text 137 72 All OSC messages received on port 3475 will be forwarded
-to matching children params.;
#X obj -3 81 tof/OSCToParam 3475;
+#X text 137 72 All OSC messages received on port 3475 will be forwarded
+to matching params.;
diff --git a/help/menubutton-help.pd b/help/menubutton-help.pd
new file mode 100644
index 0000000..6566476
--- /dev/null
+++ b/help/menubutton-help.pd
@@ -0,0 +1,63 @@
+#N canvas 1323 101 834 600 10;
+#X obj 55 365 tof/menubutton 124 25 empty empty 1 #000000 #ffffff #ff0000
+#3a12ff a b c d e f;
+#X msg 92 55 add a b c d e f;
+#X msg 52 11 clear;
+#X msg 142 124 saveitems \$1;
+#X obj 142 96 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
+1;
+#X floatatom 208 509 5 0 0 0 - - -;
+#X text 95 10 Clear menu items;
+#X text 196 53 Add menu items;
+#X obj 59 477 r \$0s;
+#X obj 208 538 send \$0r;
+#X text 188 368 [tof/menubutton] creation arguments:;
+#X text 415 373 1: width;
+#X text 415 387 2: height;
+#X text 415 400 3: send name;
+#X text 415 412 4: receive name;
+#X text 168 94 Set the saving of the menu items in the patch. Off by
+default.;
+#X text 313 324 To move the menubutton \, switch to edit mode and draw
+a selection rectangle around it. A blue handle will appear. Drag this
+handle to move the menubutton.;
+#X floatatom 264 243 5 0 0 0 - - -;
+#X obj 54 405 unpack f s;
+#X floatatom 54 428 5 0 0 0 - - -;
+#X symbolatom 113 426 10 0 0 0 - - -;
+#X floatatom 59 544 5 0 0 0 - - -;
+#X symbolatom 116 542 10 0 0 0 - - -;
+#X obj 59 513 unpack f s;
+#X text 304 242 Select and output a menu item;
+#X msg 289 268 set b;
+#X text 338 270 Select an item without outputing it;
+#X msg 308 292 set 2;
+#X text 459 174 values can be tk colors(red \, blue \, etc) or html
+colors (#ffffff);
+#X msg 260 215 colors default;
+#X text 199 147 colors: background foreground highlight contour;
+#X text 415 422 5: save menu items;
+#X text 414 434 6: background color;
+#X text 414 447 7: foreground color;
+#X text 414 458 8: highlight color;
+#X text 413 480 10+: menu items;
+#X text 415 469 9: contour color;
+#X msg 202 170 colors green red orange purple;
+#X msg 222 195 colors #000000 #ffffff #ff0000 #3a12ff;
+#X connect 0 0 18 0;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 3 0 0 0;
+#X connect 4 0 3 0;
+#X connect 5 0 9 0;
+#X connect 8 0 23 0;
+#X connect 17 0 0 0;
+#X connect 18 0 19 0;
+#X connect 18 1 20 0;
+#X connect 23 0 21 0;
+#X connect 23 1 22 0;
+#X connect 25 0 0 0;
+#X connect 27 0 0 0;
+#X connect 29 0 0 0;
+#X connect 37 0 0 0;
+#X connect 38 0 0 0;
diff --git a/src/Makefile b/src/Makefile
index 149c494..b9e35ea 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,4 +1,4 @@
-default: argument getdollarzero breakpoints~ phasorshot~ streamMinMax iterate param crossfade~ path onlyone openHelp folderpanel common~ increment listUnfold arguments breakpoints
+default: argument getdollarzero breakpoints~ phasorshot~ streamMinMax iterate param crossfade~ path onlyone openHelp folderpanel common~ increment listUnfold arguments breakpoints menubutton
current:
echo make class
diff --git a/src/menubutton.c b/src/menubutton.c
new file mode 100644
index 0000000..bba287c
--- /dev/null
+++ b/src/menubutton.c
@@ -0,0 +1,477 @@
+/* menubutton widget for PD *
+ * Based on:
+ * menubutton by Ben Bogart
+ * and button from GGEE by Guenter Geiger *
+
+ * This program is distributed under the terms of the GNU General Public *
+ * License *
+
+ * menubutton is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+
+ * menubutton is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. */
+
+
+
+
+/* Append " x " to the following line to show debugging messages */
+#define DEBUG(x)
+
+
+#include <m_pd.h>
+#include <g_canvas.h>
+#include <stdio.h>
+#include <string.h>
+
+
+#define HANDLEWIDTH 10
+
+#ifndef IOWIDTH
+#define IOWIDTH 4
+#endif
+
+
+
+
+typedef struct _menubutton
+{
+ t_object x_obj;
+
+ t_glist * x_glist;
+ //t_outlet* out2;
+ //int x_rect_width;
+ //int x_rect_height;
+ t_symbol* x_sym;
+
+ int x_height;
+ int x_width;
+
+ int current_selection;
+ int x_num_options;
+ t_symbol* bg_color;
+ t_symbol* fg_color;
+ t_symbol* hi_color;
+ t_symbol* co_color;
+ int saveitems;
+
+ t_symbol* send;
+ t_symbol* receive;
+
+ int send_set;
+ int receive_set;
+
+ t_symbol* s_empty;
+ t_symbol* s_;
+ //t_symbol* x_name;
+
+ t_symbol** x_options;
+ int x_maxoptions;
+
+ //t_symbol** current_options;
+
+ int initialized; /* 1 when we are allowed to draw, 0 otherwise */
+ int x_disabled; /* when disabled, graphical chosing is prohibited */
+} t_menubutton;
+
+
+#include "menubutton_w.h"
+
+
+
+static void menubutton_output(t_menubutton* x)
+{
+
+
+ t_atom atoms[2];
+ SETFLOAT(atoms,x->current_selection);
+ SETSYMBOL(atoms+1,x->x_options[x->current_selection]);
+ outlet_list(x->x_obj.ob_outlet, &s_list, 2, atoms);
+ if ( x->send != x->s_empty && x->send->s_thing) pd_forwardmess(x->send->s_thing, 2,atoms);
+
+}
+
+
+static void menubutton_callback(t_menubutton* x, t_floatarg f)
+{
+ //DEBUG(post("output start");)
+ x->current_selection= f;
+ menubutton_output(x);
+
+}
+static void menubutton_save(t_gobj *z, t_binbuf *b)
+{
+ DEBUG(post("save start");)
+
+
+ t_menubutton *x = (t_menubutton *)z;
+
+ t_atom* creation = binbuf_getvec(x->x_obj.te_binbuf);
+
+
+ t_symbol* send = x->s_empty;
+ t_symbol* receive = x->s_empty;
+ char buf[80];
+ if ( x->send_set ) {
+ atom_string(creation + 3, buf, 80);
+ send = gensym(buf);
+ }
+
+ if ( x->receive_set ) {
+ atom_string(creation + 4, buf, 80);
+ receive = gensym(buf);
+ }
+
+ DEBUG(post("send: %s receive: %s",send->s_name,receive->s_name);)
+
+ binbuf_addv(b, "ssiisiississss", gensym("#X"), gensym("obj"),
+ x->x_obj.te_xpix, x->x_obj.te_ypix ,
+ atom_getsymbol(creation),
+ x->x_width, x->x_height, send,receive,x->saveitems,
+ x->bg_color, x->fg_color,x->hi_color,x->co_color);
+
+ // Loop for menu items
+ int i;
+ if ( x->saveitems) {
+ for(i=0 ; i<x->x_num_options ; i++)
+ {
+ DEBUG(post("saving option: %s",x->x_options[i]->s_name);)
+ binbuf_addv(b, "s", x->x_options[i]);
+ }
+ }
+ binbuf_addv(b, ";");
+
+ DEBUG(post("save end");)
+}
+
+
+static void menubutton_clear(t_menubutton* x) {
+
+ x->x_num_options = 0;
+ x->current_selection = -1;
+ if ( menubutton_w_is_visible(x) ) {
+ menubutton_w_clear(x);
+ }
+}
+
+
+
+static void menubutton_add(t_menubutton* x, t_symbol *s, int argc, t_atom *argv) {
+
+ int visible = menubutton_w_is_visible(x);
+
+ // resize the options-array if it is too small
+ if((argc + x->x_num_options) > x->x_maxoptions){
+
+ x->x_options = resizebytes( x->x_options, x->x_maxoptions*sizeof(*(x->x_options)),
+ (argc + x->x_num_options+10)*sizeof(*(x->x_options)));
+ x->x_maxoptions=argc + x->x_num_options+10;
+ }
+
+ int i;
+ t_symbol* label;
+ for ( i=0;i<argc;i++) {
+ if ((argv+i)->a_type==A_SYMBOL) {
+
+ label = atom_getsymbol(argv+i);
+ DEBUG(post("adding option: %s",label->s_name);)
+ x->x_options[x->x_num_options] = label;
+ if ( visible ) {
+ menubutton_w_additem( x,label,x->x_num_options);
+ }
+ x->x_num_options = x->x_num_options + 1;
+ }
+
+ }
+
+
+}
+
+
+
+// function to change the colors
+
+static void menubutton_colors(t_menubutton* x, t_symbol* s, int argc, t_atom* argv)
+{
+
+ DEBUG(post("bgcolour start");)
+
+ if ( argc && argv->a_type==A_SYMBOL && atom_getsymbol(argv)==gensym("default")) {
+ x->bg_color = gensym("grey90");
+ x->fg_color = gensym("black");
+ x->hi_color = gensym("grey95");
+ x->co_color = gensym("black");
+ } else {
+
+ if (argc > 4) argc = 4;
+ switch (argc) {
+ case 4: if ((argv+3)->a_type==A_SYMBOL) x->co_color = atom_getsymbol(argv+3);
+ case 3: if ((argv+2)->a_type==A_SYMBOL) x->hi_color = atom_getsymbol(argv+2);
+ case 2: if ((argv+1)->a_type==A_SYMBOL) x->fg_color = atom_getsymbol(argv+1);
+ case 1: if ((argv)->a_type==A_SYMBOL) x->bg_color = atom_getsymbol(argv);
+ break;
+ }
+ }
+
+ if(menubutton_w_is_visible(x)) {
+ //sys_vgui(".x%x.c.s%x configure -background \"%s\" -foreground \"%s\"\n", x->x_glist, x, x->bg_color->s_name,x->fg_color->s_name);
+ menubutton_w_apply_colors(x);
+ }
+}
+
+
+static int menubutton_set_float(t_menubutton* x, t_floatarg item) {
+
+
+ int i=(int)item;
+ if( (i < x->x_num_options) && (i >= 0)) {
+ x->current_selection = i;
+ if(menubutton_w_is_visible(x)) menubutton_w_text(x,x->x_options[x->current_selection]);
+ return 1;
+ } else {
+ return 0;
+ }
+
+}
+
+/* Function to select a menu option by inlet */
+static void menubutton_float(t_menubutton* x, t_floatarg item)
+{
+ DEBUG(post("iselect start");)
+
+ if ( menubutton_set_float(x,item) ) {
+ menubutton_output(x);
+ } else {
+ pd_error(x,"menubutton: expecting value between 0 and %i",x->x_num_options);
+ }
+
+ DEBUG(post("iselect end");)
+}
+
+static int menubutton_set_symbol(t_menubutton* x, t_symbol *s) {
+
+
+ int i;
+
+ /* Compare inlet symbol to each option */
+ for(i=0; i < x->x_num_options; i++) {
+ if(x->x_options[i]->s_name == s->s_name) {
+ x->current_selection = i;
+ if(menubutton_w_is_visible(x)) menubutton_w_text(x,s);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+/* Function to choose value via symbol name */
+static void menubutton_symbol(t_menubutton* x, t_symbol *s)
+{
+ if(menubutton_set_symbol(x,s)) {
+ menubutton_output(x);
+ } else {
+ post("menubutton: '%s' is not an available option.", s->s_name);
+ }
+
+}
+
+/* Function to choose value via name/index but without outputting it*/
+static void menubutton_set(t_menubutton* x, t_symbol *S, int argc, t_atom*argv)
+{
+ if(!argc)return;
+
+ if(argv->a_type==A_FLOAT) {
+ menubutton_set_float(x,atom_getfloat(argv));
+ } else if(argv->a_type==A_SYMBOL) {
+ menubutton_set_symbol(x,atom_getsymbol(argv));
+ } else {
+ pd_error(x, "menubutton: can only 'set' symbols or floats");
+ }
+}
+
+
+
+
+
+
+static t_class *menubutton_class;
+
+
+static void menubutton_receive(t_menubutton* x, t_symbol* s) {
+ if ( x->receive != x->s_empty ) pd_unbind(&x->x_obj.ob_pd, x->receive);
+ if ( s == x->s_empty || s == x->s_) {
+ x->receive = x->s_empty;
+ } else {
+ x->receive = s;
+ pd_bind(&x->x_obj.ob_pd, x->receive);
+ }
+
+}
+
+static void menubutton_send(t_menubutton* x, t_symbol* s) {
+
+ if ( s == x->s_empty || s == x->s_ ) {
+ x->send = x->s_empty;
+ } else {
+ x->send = s;
+ }
+
+
+
+}
+
+static void menubutton_free(t_menubutton*x)
+{
+ if(x->x_options)freebytes(x->x_options, sizeof(t_symbol*)*x->x_maxoptions);
+ pd_unbind(&x->x_obj.ob_pd, x->x_sym);
+
+ if ( x->receive != x->s_empty ) pd_unbind(&x->x_obj.ob_pd, x->receive);
+}
+
+static void menubutton_saveitems( t_menubutton* x, t_float f) {
+ x->saveitems = (f != 0);
+}
+
+
+static void *menubutton_new(t_symbol *s, int argc, t_atom *argv)
+{
+ DEBUG(post("menubutton new start");)
+
+ t_menubutton *x = (t_menubutton *)pd_new(menubutton_class);
+ int i;
+ char buf[256];
+
+ x->x_glist = (t_glist*)NULL;
+
+ x->x_height = 25;
+ x->current_selection = -1;
+
+ x->x_maxoptions=10;
+ x->x_options=(t_symbol**)getbytes(sizeof(t_symbol*)*x->x_maxoptions);
+ //x->current_options=(t_symbol**)getbytes(sizeof(t_symbol*)*x->x_maxoptions);
+ x->x_num_options = 0 ;
+ //x->x_options[0] = gensym("");
+
+ x->x_width = 124;
+ x->x_height = 25;
+
+ // These should match the default colors in menubutton_colors
+ x->bg_color = gensym("grey90");
+ x->fg_color = gensym("black");
+ x->hi_color = gensym("grey95");
+ x->co_color = gensym("black");
+ x->saveitems = 0;
+
+ x->s_empty = gensym("empty");
+ x->s_ = gensym("");
+
+ x->send = x->s_empty;
+ x->receive = x->s_empty;
+ x->send_set =0;
+ x->receive_set =0;
+
+ x->initialized=0;
+
+ x->x_disabled=0;
+
+ int conf_argc = argc;
+ if (conf_argc > 9) conf_argc = 9;
+ switch(conf_argc){
+ case 9: if ((argv+8)->a_type==A_SYMBOL) x->co_color = atom_getsymbol(argv+8);
+ case 8: if ((argv+7)->a_type==A_SYMBOL) x->hi_color = atom_getsymbol(argv+7);
+ case 7: if ((argv+6)->a_type==A_SYMBOL) x->fg_color = atom_getsymbol(argv+6);
+ case 6: if ((argv+5)->a_type==A_SYMBOL) x->bg_color = atom_getsymbol(argv+5);
+ case 5: if ((argv+4)->a_type==A_FLOAT) x->saveitems = atom_getfloat(argv+4);
+ case 4: if ((argv+3)->a_type==A_SYMBOL) {
+ x->receive = atom_getsymbol(argv+3);
+ x->receive_set =1;
+ }
+ case 3: if ((argv+2)->a_type==A_SYMBOL) {
+ x->send = atom_getsymbol(argv+2);
+ x->send_set =1;
+ }
+ case 2: if ((argv+1)->a_type==A_FLOAT) x->x_height = atom_getfloat(argv+1);
+ case 1: if ((argv)->a_type==A_FLOAT) x->x_width = atom_getfloat(argv);
+ break;
+ }
+
+ DEBUG(post("send: %s receive: %s",x->send->s_name,x->receive->s_name);)
+
+
+ // Bind receiver
+ if ( x->receive != x->s_empty ) pd_bind(&x->x_obj.ob_pd, x->receive);
+
+
+ /* Bind the recieve "menubutton%p" to the widget outlet*/
+ sprintf(buf,"menubutton%p",x);
+ x->x_sym = gensym(buf);
+ pd_bind(&x->x_obj.ob_pd, x->x_sym);
+
+ /* define proc in tcl/tk where "menubutton%p" is the receive, "callback" is the method, and "$index" is an argument. */
+ sys_vgui("proc select%x {index} {\n pd [concat menubutton%p callback $index \\;]\n }\n",x,x);
+
+
+ outlet_new(&x->x_obj, &s_symbol);
+
+
+ if (argc > 9) menubutton_add(x,&s_list,argc-9,argv+9);
+
+
+DEBUG(post("menubutton new end");)
+
+ return (x);
+}
+
+void menubutton_setup(void) {
+
+ DEBUG(post("setup start");)
+
+ menubutton_class = class_new(gensym("menubutton"), (t_newmethod)menubutton_new, (t_method)menubutton_free,
+ sizeof(t_menubutton),0,A_GIMME,0);
+
+ class_addmethod(menubutton_class, (t_method)menubutton_callback,
+ gensym("callback"),A_DEFFLOAT,0);
+
+ class_addmethod(menubutton_class, (t_method)menubutton_send,
+ gensym("send"),A_DEFSYMBOL,0);
+
+ class_addmethod(menubutton_class, (t_method)menubutton_receive,
+ gensym("receive"),A_DEFSYMBOL,0);
+
+ class_addmethod(menubutton_class, (t_method)menubutton_saveitems,
+ gensym("saveitems"),A_FLOAT,0);
+
+ class_addmethod(menubutton_class, (t_method)menubutton_add,
+ gensym("add"), A_GIMME,0);
+
+ class_addmethod(menubutton_class, (t_method)menubutton_clear,
+ gensym("clear"), 0);
+
+ class_addmethod(menubutton_class, (t_method)menubutton_colors,
+ gensym("colors"),A_GIMME,0);
+
+
+
+ class_addmethod(menubutton_class, (t_method)menubutton_set,
+ gensym("set"),A_GIMME,0);
+
+ class_addsymbol(menubutton_class, (t_method)menubutton_symbol);
+
+ class_addfloat(menubutton_class, (t_method)menubutton_float);
+
+
+
+ class_setwidget(menubutton_class,&menubutton_widgetbehavior);
+
+ class_setsavefn(menubutton_class,&menubutton_save);
+
+
+ post("menubutton v0.01 tof, based on popup by Ben Bogart and button by ggee");
+}
+
+
diff --git a/src/menubutton_w.h b/src/menubutton_w.h
new file mode 100644
index 0000000..8166d83
--- /dev/null
+++ b/src/menubutton_w.h
@@ -0,0 +1,372 @@
+
+#define UPDATE 0
+#define CREATE 1
+#define DESTROY 2
+
+static int menubutton_w_is_visible(t_menubutton* x) {
+
+ return (x->x_glist)?glist_isvisible(x->x_glist):0;
+
+}
+
+
+static void menubutton_w_disable(t_menubutton*x, t_float f){
+
+ int i = (int)f;
+ sys_vgui(".x%x.c.s%x configure -state \"%s\"\n", x->x_glist, x, i?"disabled":"active");
+}
+
+static void menubutton_w_text(t_menubutton* x, t_symbol* s) {
+sys_vgui(".x%x.c.s%x configure -text \"%s\"\n",x->x_glist, x, s->s_name);
+}
+
+static void menubutton_w_clear(t_menubutton* x){
+ sys_vgui(".x%x.c.s%x.menu delete 0 end ; .x%x.c.s%x configure -text \"%s\"\n", x->x_glist, x,x->x_glist, x,"");
+ //sys_vgui(".x%x.c.s%x.menu delete 0 end \n", x->x_glist, x);
+ //sys_vgui(".x%x.c.s%x configure -text \"%s\"\n", x->x_glist, x,"");
+
+}
+
+static void menubutton_w_additem(t_menubutton* x, t_symbol *label, int i) {
+ sys_vgui(".x%x.c.s%x.menu add command -label \"%s\" -command {.x%x.c.s%x configure -text \"%s\" ; select%x \"%d\"} \n",
+ x->x_glist, x, label->s_name, x->x_glist, x, label->s_name, x, i);
+
+}
+
+static void menubutton_w_apply_colors(t_menubutton* x) {
+
+ sys_vgui(".x%x.c.s%x configure -background \"%s\" -foreground \"%s\" -activeforeground \"%s\" -activebackground \"%s\"\n",
+ x->x_glist, x, x->bg_color->s_name,x->fg_color->s_name,x->fg_color->s_name,x->hi_color->s_name);
+
+ sys_vgui(".x%x.c.s%x.menu configure -background \"%s\" -foreground \"%s\" -activeforeground \"%s\" -activebackground \"%s\"\n",
+ x->x_glist, x, x->bg_color->s_name,x->fg_color->s_name,x->fg_color->s_name,x->hi_color->s_name);
+
+ sys_vgui(".x%x.c itemconfigure %xR -outline \"%s\"\n", x->x_glist, x,x->co_color->s_name);
+}
+
+
+
+
+static void menubutton_w_draw_inlets(t_menubutton *x, t_glist *glist, int draw, int nin, int nout)
+{
+ /* outlets */
+ int n = nin;
+ int nplus, i;
+ nplus = (n == 1 ? 1 : n-1);
+ DEBUG(post("draw inlet");)
+ for (i = 0; i < n; i++)
+ {
+ int onset = text_xpix(&x->x_obj, glist) + (x->x_width - IOWIDTH) * i / nplus;
+ if (draw==CREATE) {
+ sys_vgui(".x%x.c create rectangle %d %d %d %d -outline blue -tags {%xo%d %xo}\n",
+ glist_getcanvas(glist),
+ onset, text_ypix(&x->x_obj, glist) + x->x_height + 1 ,
+ onset + IOWIDTH, text_ypix(&x->x_obj, glist) + x->x_height+2,
+ x, i, x);
+ } else if (draw==UPDATE) {
+ sys_vgui(".x%x.c coords %xo%d %d %d %d %d\n",
+ glist_getcanvas(glist), x, i,
+ onset, text_ypix(&x->x_obj, glist) + x->x_height +1,
+ onset + IOWIDTH, text_ypix(&x->x_obj, glist) + x->x_height+2);
+ } else {
+
+ sys_vgui(".x%x.c delete %xo\n",glist_getcanvas(glist),x); // Added tag for all outlets of one instance
+ }
+ }
+ /* inlets */
+ n = nout;
+ nplus = (n == 1 ? 1 : n-1);
+ for (i = 0; i < n; i++)
+ {
+ int onset = text_xpix(&x->x_obj, glist) + (x->x_width - IOWIDTH) * i / nplus;
+ if (draw==CREATE) {
+ sys_vgui(".x%x.c create rectangle %d %d %d %d -outline blue -tags {%xi%d %xi}\n",
+ glist_getcanvas(glist),
+ onset, text_ypix(&x->x_obj, glist)-2,
+ onset + IOWIDTH, text_ypix(&x->x_obj, glist)-1,
+ x, i, x);
+ } else if (draw==UPDATE) {
+ sys_vgui(".x%x.c coords %xi%d %d %d %d %d\n",
+ glist_getcanvas(glist), x, i,
+ onset, text_ypix(&x->x_obj, glist)-2,
+ onset + IOWIDTH, text_ypix(&x->x_obj, glist)-1);
+ } else {
+ sys_vgui(".x%x.c delete %xi\n",glist_getcanvas(glist),x); // Added tag for all inlets of one instance
+ }
+ }
+ DEBUG(post("draw inlet end");)
+}
+
+
+static void menubutton_w_draw_handle(t_menubutton *x, t_glist *glist, int draw) {
+
+ DEBUG(post("draw_handle start: %i",draw);)
+ int onset = text_xpix(&x->x_obj, glist) + (x->x_width) ;
+
+ if (draw==CREATE) {
+ sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xhandle -outline blue -fill blue\n",
+ glist_getcanvas(glist),
+ onset, text_ypix(&x->x_obj, glist) ,
+ onset + HANDLEWIDTH, text_ypix(&x->x_obj, glist) + x->x_height ,
+ x);
+ } else if (draw==UPDATE) {
+ sys_vgui(".x%x.c coords %xhandle %d %d %d %d\n",
+ glist_getcanvas(glist), x,
+ onset, text_ypix(&x->x_obj, glist) ,
+ onset + HANDLEWIDTH, text_ypix(&x->x_obj, glist) + x->x_height );
+ } else {
+ sys_vgui(".x%x.c delete %xhandle\n",glist_getcanvas(glist),x,0);
+ }
+
+
+ DEBUG(post("draw_handle end");)
+}
+
+
+static void menubutton_w_create_widget(t_menubutton *x)
+{
+ DEBUG(post("create_widget start");)
+
+ char text[MAXPDSTRING];
+ int len,i;
+ t_symbol* temp_name;
+
+
+
+ /* Create menubutton and empty menu widget -- maybe the menu should be created elseware?*/
+
+ /* draw using the last name if it was selected otherwise use default name. */
+ if(x->current_selection < 0)
+ {
+ temp_name = gensym("");
+ } else {
+ temp_name = x->x_options[x->current_selection];
+ }
+
+ /* Seems we have to delete the widget in case it already exists (Provided by Guenter)*/
+
+ if(x->initialized)
+ DEBUG(post("destroying previous widget");)
+ {
+ sys_vgui("destroy .x%x.c.s%x\n",x->x_glist,x);
+
+ // Create menubutton and menu
+ sys_vgui("set %xw .x%x.c.s%x ; menubutton $%xw -justify left -relief flat -anchor w -indicatoron 0 -text \"%s\" -direction flush -menu $%xw.menu ; menu $%xw.menu -relief solid -tearoff 0 \n",
+ x,x->x_glist,x,x,temp_name->s_name,x,x);
+
+ menubutton_w_apply_colors(x);
+ for(i=0 ; i<x->x_num_options ; i++)
+ {
+ // Add menu itmes
+ menubutton_w_additem(x,x->x_options[i],i);
+ }
+ }
+
+ DEBUG(post("id: .x%x.c.s%x", x->x_glist, x);)
+ DEBUG(post("create_widget end");)
+}
+
+
+static void menubutton_w_draw_contour(t_menubutton *x, t_glist *glist, int draw) {
+
+ int onset = text_xpix(&x->x_obj, glist);
+ if (draw==CREATE) {
+ sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xR -outline \"%s\" \n",
+ glist,
+ onset, text_ypix(&x->x_obj, glist) ,
+ onset + x->x_width, text_ypix(&x->x_obj, glist) + x->x_height,
+ x,x->co_color->s_name); //"green"
+ } else if (draw==UPDATE) {
+ sys_vgui(".x%x.c coords %xR %d %d %d %d\n",
+ glist, x,
+ onset, text_ypix(&x->x_obj, glist) ,
+ onset + x->x_width, text_ypix(&x->x_obj, glist) + x->x_height );
+ } else {
+ sys_vgui(".x%x.c delete %xR\n",glist_getcanvas(glist),x,0);
+ }
+
+}
+
+
+static void menubutton_w_drawme(t_menubutton *x, t_glist *glist, int draw)
+{
+ t_canvas *canvas=glist_getcanvas(glist);
+ DEBUG(post("drawme start");)
+
+
+
+ DEBUG(post("drawme %d",draw);)
+ if (draw==CREATE) {
+ /* by drawing, we "initialize" the popup */
+ x->initialized=1;
+
+ DEBUG(post("glist %x canvas %x",x->x_glist,canvas);)
+ menubutton_w_draw_contour(x,glist,CREATE);
+ x->x_glist = canvas;
+ menubutton_w_create_widget(x);
+
+ sys_vgui(".x%x.c create window %d %d -width %d -height %d -anchor nw -window .x%x.c.s%x -tags %xS\n",
+ canvas,text_xpix(&x->x_obj, glist) + 1, text_ypix(&x->x_obj, glist) + 1, x->x_width -1, x->x_height -1, x->x_glist,x,x);
+
+ }
+ else if (draw==UPDATE) {
+ menubutton_w_draw_contour(x,glist,UPDATE);
+ sys_vgui(".x%x.c coords %xS %d %d\n",
+ canvas, x,
+ text_xpix(&x->x_obj, glist) + 1, text_ypix(&x->x_obj, glist) +1);
+ } else {
+
+ DEBUG(post("erase start");)
+ if(x->initialized){
+ menubutton_w_draw_contour(x,glist,DESTROY);
+ sys_vgui("destroy .x%x.c.s%x\n",glist_getcanvas(glist),x);
+ sys_vgui(".x%x.c delete %xS\n",glist_getcanvas(glist), x);
+
+ }
+ DEBUG(post("erase end");)
+
+ }
+
+ // menubutton_w_draw_handle(x, glist, firsttime);
+ //sys_vgui(".x%x.c.s%x configure -state \"%s\"\n", canvas, x, x->x_disabled?"disabled":"active");
+
+
+ // Output a bang to first outlet when we're ready to receive float messages the first time!.
+ // Too bad this is NOT always the first time... window shading makes the bang go out again. :(
+ //if(firsttime) {outlet_bang(x->x_obj.ob_outlet);}
+
+ DEBUG(post("drawme end");)
+}
+
+
+
+/* ------------------------ popup widgetbehaviour----------------------------- */
+
+
+static void menubutton_w_getrect(t_gobj *z, t_glist *owner,
+ int *xp1, int *yp1, int *xp2, int *yp2)
+{
+ // DEBUG(post("getrect start");)
+
+ int width, height;
+ t_menubutton* s = (t_menubutton*)z;
+
+ width = s->x_width;
+ height = s->x_height;
+ *xp1 = text_xpix(&s->x_obj, owner) ;
+ *yp1 = text_ypix(&s->x_obj, owner) ;
+ *xp2 = text_xpix(&s->x_obj, owner) + width + HANDLEWIDTH ;
+ *yp2 = text_ypix(&s->x_obj, owner) + height ;
+
+ // DEBUG(post("getrect end");)
+}
+
+static void menubutton_w_displace(t_gobj *z, t_glist *glist,
+ int dx, int dy)
+{
+ t_menubutton *x = (t_menubutton *)z;
+ DEBUG(post("displace start");)
+ x->x_obj.te_xpix += dx;
+ x->x_obj.te_ypix += dy;
+ if (glist_isvisible(glist))
+ {
+ menubutton_w_draw_handle(x,glist,UPDATE);
+ menubutton_w_draw_inlets(x, glist, UPDATE, 1,1);
+ menubutton_w_drawme(x, glist, UPDATE);
+ canvas_fixlinesfor(glist_getcanvas(glist),(t_text*) x);
+ }
+ DEBUG(post("displace end");)
+}
+
+static void menubutton_w_select(t_gobj *z, t_glist *glist, int state)
+{
+ DEBUG(post("select start");)
+
+ t_menubutton *x = (t_menubutton *)z;
+ if(x->initialized){
+ /*
+ sys_vgui(".x%x.c itemconfigure %xhandle -fill %s\n", glist,
+ x, (state? "blue" : x->fg_color->s_name));
+ */
+ if (state) {
+ menubutton_w_draw_handle(x,glist,CREATE);
+ menubutton_w_draw_inlets(x, glist, CREATE, 1,1);
+ menubutton_w_disable(x,1);
+ }
+ else {
+ menubutton_w_disable(x,0);
+ menubutton_w_draw_handle(x,glist,DESTROY);
+ menubutton_w_draw_inlets(x,glist,DESTROY,1,1);
+
+ }
+ }
+
+ DEBUG(post("select end");)
+}
+
+
+
+static void menubutton_w_delete(t_gobj *z, t_glist *glist)
+{
+ DEBUG(post("delete start");)
+
+ t_text *x = (t_text *)z;
+ canvas_deletelinesfor(glist, x);
+
+ DEBUG(post("delete end");)
+}
+
+
+static void menubutton_w_vis(t_gobj *z, t_glist *glist, int vis)
+{
+ t_menubutton* s = (t_menubutton*)z;
+ t_rtext *y;
+ DEBUG(post("vis start");)
+ DEBUG(post("vis: %d",vis);)
+ if (vis) {
+
+#ifdef PD_MINOR_VERSION
+ // JMZ: create an editor if there is none;
+ // on 0.42 there might be none IF [popup] is contained within a gop
+
+#if PD_MINOR_VERSION > 41
+ canvas_create_editor(glist);
+#endif
+ y = (t_rtext *) rtext_new(glist, (t_text *)z);
+#else
+ y = (t_rtext *) rtext_new(glist, (t_text *)z,0,0);
+#endif
+
+ menubutton_w_drawme(s, glist, CREATE);
+
+ }
+ else {
+ y = glist_findrtext(glist, (t_text *)z);
+ menubutton_w_drawme(s, glist, DESTROY);
+ rtext_free(y);
+ }
+
+ DEBUG(post("vis end");)
+}
+
+/*
+static int menubutton_w_newclick(t_menubutton *x, struct _glist *glist,
+ int xpos, int ypos, int shift, int alt, int dbl, int doit) {
+
+ post("x: %i,y: %i,shift: %i, alt: %i, dbl: %i, doit: %i",xpos,ypos,shift,alt,dbl,doit);
+
+ return (1);
+ }
+*/
+
+
+t_widgetbehavior menubutton_widgetbehavior = {
+ w_getrectfn: menubutton_w_getrect,
+ w_displacefn: menubutton_w_displace,
+ w_selectfn: menubutton_w_select,
+ w_activatefn: NULL,
+ w_deletefn: menubutton_w_delete,
+ w_visfn: menubutton_w_vis,
+ w_clickfn: NULL,
+ //w_clickfn: (t_clickfn)menubutton_w_newclick,
+};
diff --git a/src/paramGui.h b/src/paramGui.h
index 1d44a17..2cef335 100644
--- a/src/paramGui.h
+++ b/src/paramGui.h
@@ -258,8 +258,7 @@ static void paramGui_buildCanvas(t_paramGui* x,int x_position,int y_position) {
x->childcanvas->gl_screeny1 = y_position;
x->childcanvas->gl_screenx2 = pos_x + 300 + x->childcanvas->gl_screenx1;
x->childcanvas->gl_screeny2 = pos_y + 30 + x->childcanvas->gl_screeny1;
- //post("size: %i %i %i %i",x->childcanvas->gl_screenx1,x->childcanvas->gl_screeny1,\
- x->childcanvas->gl_screenx2,x->childcanvas->gl_screeny2);
+
// Change the build flag