aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas O Fredericks <mrtof@users.sourceforge.net>2009-11-05 23:31:16 +0000
committerThomas O Fredericks <mrtof@users.sourceforge.net>2009-11-05 23:31:16 +0000
commit9c3ae143b3d288c1363a191d7175383135dd0de0 (patch)
treed6b21f77dd5797dd58e64c959cf3d7b408df155b
parent09f42b21764953749f83accbf01948bc4b318577 (diff)
A few fixes and a new pmenu test
svn path=/trunk/externals/tof/; revision=12723
-rw-r--r--help/menubutton-help.pd21
-rw-r--r--src/menubutton.c23
-rw-r--r--src/menubutton_w.h18
-rw-r--r--test/pmenu-help.pd29
-rw-r--r--test/pmenu.c482
-rw-r--r--test/pmenu_w.h331
6 files changed, 893 insertions, 11 deletions
diff --git a/help/menubutton-help.pd b/help/menubutton-help.pd
index 6566476..538514f 100644
--- a/help/menubutton-help.pd
+++ b/help/menubutton-help.pd
@@ -1,14 +1,14 @@
#N canvas 1323 101 834 600 10;
-#X obj 55 365 tof/menubutton 124 25 empty empty 1 #000000 #ffffff #ff0000
+#X obj 54 358 tof/menubutton 132 22 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 80 33 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
+#X obj 142 106 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 text 184 31 Add menu items;
#X obj 59 477 r \$0s;
#X obj 208 538 send \$0r;
#X text 188 368 [tof/menubutton] creation arguments:;
@@ -16,8 +16,8 @@
#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 229 111 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.;
@@ -44,6 +44,13 @@ colors (#ffffff);
#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 text 182 55 Set its size;
+#X msg 103 56 size 102 32;
+#X text 202 77 Set its size;
+#X msg 123 78 size 132 22;
+#N canvas 0 0 742 557 test 1;
+#X coords 0 -1 1 1 300 200 1;
+#X restore 556 538 pd test;
#X connect 0 0 18 0;
#X connect 1 0 0 0;
#X connect 2 0 0 0;
@@ -61,3 +68,5 @@ colors (#ffffff);
#X connect 29 0 0 0;
#X connect 37 0 0 0;
#X connect 38 0 0 0;
+#X connect 40 0 0 0;
+#X connect 42 0 0 0;
diff --git a/src/menubutton.c b/src/menubutton.c
index bba287c..a96d81d 100644
--- a/src/menubutton.c
+++ b/src/menubutton.c
@@ -158,6 +158,23 @@ static void menubutton_clear(t_menubutton* x) {
}
}
+static void menubutton_size(t_menubutton* x,t_symbol *s, int argc, t_atom *argv) {
+
+ if (argc>2) argc =2;
+ switch (argc) {
+ 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;
+ }
+
+ if ( x->x_width < 10) x->x_width = 10;
+ if ( x->x_height < 10) x->x_height = 10;
+
+ if ( menubutton_w_is_visible(x) ) {
+ menubutton_w_resize(x);
+ }
+}
+
static void menubutton_add(t_menubutton* x, t_symbol *s, int argc, t_atom *argv) {
@@ -403,6 +420,9 @@ static void *menubutton_new(t_symbol *s, int argc, t_atom *argv)
DEBUG(post("send: %s receive: %s",x->send->s_name,x->receive->s_name);)
+ if ( x->x_width < 10) x->x_width = 10;
+ if ( x->x_height < 10) x->x_height = 10;
+
// Bind receiver
if ( x->receive != x->s_empty ) pd_bind(&x->x_obj.ob_pd, x->receive);
@@ -455,7 +475,8 @@ void menubutton_setup(void) {
class_addmethod(menubutton_class, (t_method)menubutton_colors,
gensym("colors"),A_GIMME,0);
-
+ class_addmethod(menubutton_class, (t_method)menubutton_size,
+ gensym("size"),A_GIMME,0);
class_addmethod(menubutton_class, (t_method)menubutton_set,
gensym("set"),A_GIMME,0);
diff --git a/src/menubutton_w.h b/src/menubutton_w.h
index 8166d83..b519463 100644
--- a/src/menubutton_w.h
+++ b/src/menubutton_w.h
@@ -10,6 +10,9 @@ static int menubutton_w_is_visible(t_menubutton* x) {
}
+
+
+
static void menubutton_w_disable(t_menubutton*x, t_float f){
int i = (int)f;
@@ -151,7 +154,8 @@ static void menubutton_w_create_widget(t_menubutton *x)
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",
+
+ sys_vgui("set %xw .x%x.c.s%x ; menubutton $%xw -justify left -relief flat -anchor e -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);
@@ -172,13 +176,13 @@ 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,
+ glist_getcanvas(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"
+ x,x->co_color->s_name);
} else if (draw==UPDATE) {
sys_vgui(".x%x.c coords %xR %d %d %d %d\n",
- glist, x,
+ glist_getcanvas(glist), x,
onset, text_ypix(&x->x_obj, glist) ,
onset + x->x_width, text_ypix(&x->x_obj, glist) + x->x_height );
} else {
@@ -187,6 +191,12 @@ static void menubutton_w_draw_contour(t_menubutton *x, t_glist *glist, int draw)
}
+static void menubutton_w_resize(t_menubutton* x) {
+
+ sys_vgui(".x%x.c itemconfigure %xS -width %i -height %i \n", x->x_glist, x,x->x_width-1,x->x_height-1);
+ menubutton_w_draw_contour(x,x->x_glist,UPDATE);
+ canvas_fixlinesfor(x->x_glist,(t_text*) x);
+}
static void menubutton_w_drawme(t_menubutton *x, t_glist *glist, int draw)
{
diff --git a/test/pmenu-help.pd b/test/pmenu-help.pd
new file mode 100644
index 0000000..1775fab
--- /dev/null
+++ b/test/pmenu-help.pd
@@ -0,0 +1,29 @@
+#N canvas 1164 0 617 484 10;
+#X obj 210 274 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 228 213 key;
+#X msg 158 188 clear;
+#X obj 228 239 sel 65;
+#X text 252 275 <- Shift+A will open the menu;
+#X text 225 5 <- Select a folder here;
+#X msg 61 151 add a bb ccc dddd eeeee;
+#X obj 61 431 print;
+#X obj 252 80 tof/folderpanel;
+#X text 324 311 bg fg hi;
+#X msg 204 325 2;
+#X msg 366 334 colors green;
+#X msg 246 321 3;
+#X msg 158 225 add a;
+#X obj 61 392 tof/pmenu black white red;
+#X text 201 414 Outlets: symbol index dump;
+#X obj 376 192 soundfiler;
+#X connect 0 0 14 0;
+#X connect 1 0 3 0;
+#X connect 2 0 14 0;
+#X connect 3 0 0 0;
+#X connect 6 0 14 0;
+#X connect 10 0 14 0;
+#X connect 11 0 14 0;
+#X connect 12 0 14 0;
+#X connect 13 0 14 0;
+#X connect 14 0 7 0;
diff --git a/test/pmenu.c b/test/pmenu.c
new file mode 100644
index 0000000..ee6f2ae
--- /dev/null
+++ b/test/pmenu.c
@@ -0,0 +1,482 @@
+/* pmenu widget for PD *
+ * Based on:
+ * pmenu by Ben Bogart
+ * and button from GGEE by Guenter Geiger *
+
+ * This program is distributed under the terms of the GNU General Public *
+ * License *
+
+ * pmenu 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. *
+
+ * pmenu 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>
+
+
+
+typedef struct _pmenu
+{
+ t_object x_obj;
+
+ t_glist * x_glist;
+ //t_outlet* out2;
+ //int x_rect_width;
+ //int x_rect_height;
+ t_symbol* callback;
+
+ //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;
+ //int visible;
+
+ //t_symbol** current_options;
+
+ //int created; //1 when menu is created
+ //int x_disabled; /* when disabled, graphical chosing is prohibited */
+} t_pmenu;
+
+#include "pmenu_w.h"
+
+static void pmenu_output(t_pmenu* x)
+{
+
+
+ pmenu_w_activate(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 pmenu_callback(t_pmenu* x, t_floatarg f)
+{
+ //DEBUG(post("output start");)
+ x->current_selection= (int)f;
+ //pmenu_w_text(x,x->x_options[x->current_selection]);
+ pmenu_output(x);
+
+}
+/*
+static void pmenu_save(t_gobj *z, t_binbuf *b)
+{
+ DEBUG(post("save start");)
+
+
+ t_pmenu *x = (t_pmenu *)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 pmenu_clear(t_pmenu* x) {
+
+ x->x_num_options = 0;
+ x->current_selection = -1;
+ pmenu_w_clear(x);
+
+}
+
+/*
+static void pmenu_size(t_pmenu* x,t_symbol *s, int argc, t_atom *argv) {
+
+ if (argc>2) argc =2;
+ switch (argc) {
+ 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;
+ }
+
+ if ( x->x_width < 10) x->x_width = 10;
+ if ( x->x_height < 10) x->x_height = 10;
+
+ if ( pmenu_w_is_visible(x) ) {
+ pmenu_w_resize(x);
+ }
+}
+*/
+
+
+static void pmenu_add(t_pmenu* x, t_symbol *s, int argc, t_atom *argv) {
+
+
+
+ // 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;
+
+ pmenu_w_additem( x,label,x->x_num_options);
+
+ x->x_num_options = x->x_num_options + 1;
+ }
+
+ }
+
+
+}
+
+
+
+// function to change the colors
+
+static void pmenu_colors(t_pmenu* 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;
+ }
+ }
+
+ pmenu_w_apply_colors(x);
+
+}
+
+
+static int pmenu_set_float(t_pmenu* x, t_floatarg item) {
+
+
+ int i=(int)item;
+ if( (i < x->x_num_options) && (i >= 0)) {
+ x->current_selection = i;
+ //if(pmenu_w_is_visible(x)) pmenu_w_text(x,x->x_options[x->current_selection]);
+ return 1;
+ } else {
+ return 0;
+ }
+
+}
+
+/* Function to select a menu option by inlet */
+static void pmenu_float(t_pmenu* x, t_floatarg item)
+{
+ DEBUG(post("iselect start");)
+
+ if ( pmenu_set_float(x,item) ) {
+ pmenu_output(x);
+ } else {
+ pd_error(x,"pmenu: expecting value between 0 and %i",x->x_num_options);
+ }
+
+ DEBUG(post("iselect end");)
+}
+
+static int pmenu_set_symbol(t_pmenu* 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(pmenu_w_is_visible(x)) pmenu_w_text(x,s);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+/* Function to choose value via symbol name */
+static void pmenu_symbol(t_pmenu* x, t_symbol *s)
+{
+ if(pmenu_set_symbol(x,s)) {
+ pmenu_output(x);
+ } else {
+ post("pmenu: '%s' is not an available option.", s->s_name);
+ }
+
+}
+
+/* Function to choose value via name/index but without outputting it*/
+static void pmenu_set(t_pmenu* x, t_symbol *S, int argc, t_atom*argv)
+{
+ if(!argc)return;
+
+ if(argv->a_type==A_FLOAT) {
+ pmenu_set_float(x,atom_getfloat(argv));
+ } else if(argv->a_type==A_SYMBOL) {
+ pmenu_set_symbol(x,atom_getsymbol(argv));
+ } else {
+ pd_error(x, "pmenu: can only 'set' symbols or floats");
+ }
+}
+
+
+
+
+
+
+static t_class *pmenu_class;
+
+/*
+static void pmenu_receive(t_pmenu* 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 pmenu_send(t_pmenu* x, t_symbol* s) {
+
+ if ( s == x->s_empty || s == x->s_ ) {
+ x->send = x->s_empty;
+ } else {
+ x->send = s;
+ }
+
+
+
+}
+*/
+
+static void pmenu_free(t_pmenu*x)
+{
+ pmenu_w_menu(x,DESTROY);
+
+
+ if(x->x_options)freebytes(x->x_options, sizeof(t_symbol*)*x->x_maxoptions);
+ pd_unbind(&x->x_obj.ob_pd, x->callback);
+
+ //if ( x->receive != x->s_empty ) pd_unbind(&x->x_obj.ob_pd, x->receive);
+}
+/*
+static void pmenu_saveitems( t_pmenu* x, t_float f) {
+ x->saveitems = (f != 0);
+}
+*/
+
+static void *pmenu_new(t_symbol *s, int argc, t_atom *argv)
+{
+ DEBUG(post("pmenu new start");)
+
+ t_pmenu *x = (t_pmenu *)pd_new(pmenu_class);
+ int i;
+ char buf[256];
+
+ //x->x_glist = NULL;
+ //x->visible = 0;
+ //x->created = 0;
+
+ //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 pmenu_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->x_disabled=0;
+
+
+
+ if (argc > 4) argc = 4;
+ switch(argc){
+ case 4: if ((argv+3)->a_type==A_SYMBOL) x->hi_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;
+ }
+
+ /* Bind the recieve "pmenu%p" to the widget outlet*/
+ sprintf(buf,"pmenu%p",x);
+ x->callback = gensym(buf);
+ pd_bind(&x->x_obj.ob_pd, x->callback);
+
+ /* define proc in tcl/tk where "pmenu%p" is the receive, "callback" is the method, and "$index" is an argument. */
+ sys_vgui("proc select%x {index} {\n pd [concat pmenu%p callback $index \\;]\n }\n",x,x);
+
+
+ outlet_new(&x->x_obj, &s_symbol);
+
+ pmenu_w_menu(x,CREATE);
+ pmenu_w_apply_colors(x);
+ if (argc > 5) pmenu_add(x,&s_list,argc-5,argv+5);
+
+
+DEBUG(post("pmenu new end");)
+
+ return (x);
+}
+
+void pmenu_setup(void) {
+
+ DEBUG(post("setup start");)
+
+ pmenu_class = class_new(gensym("pmenu"), (t_newmethod)pmenu_new, (t_method)pmenu_free,
+ sizeof(t_pmenu),0,A_GIMME,0);
+
+ class_addbang(pmenu_class, (t_method)pmenu_w_pop);
+
+ class_addmethod(pmenu_class, (t_method)pmenu_callback,
+ gensym("callback"),A_DEFFLOAT,0);
+ /*
+ class_addmethod(pmenu_class, (t_method)pmenu_send,
+ gensym("send"),A_DEFSYMBOL,0);
+
+ class_addmethod(pmenu_class, (t_method)pmenu_receive,
+ gensym("receive"),A_DEFSYMBOL,0);
+
+ class_addmethod(pmenu_class, (t_method)pmenu_saveitems,
+ gensym("saveitems"),A_FLOAT,0);
+ */
+ class_addmethod(pmenu_class, (t_method)pmenu_add,
+ gensym("add"), A_GIMME,0);
+
+ class_addmethod(pmenu_class, (t_method)pmenu_clear,
+ gensym("clear"), 0);
+
+ class_addmethod(pmenu_class, (t_method)pmenu_colors,
+ gensym("colors"),A_GIMME,0);
+ /*
+ class_addmethod(pmenu_class, (t_method)pmenu_size,
+ gensym("size"),A_GIMME,0);
+ */
+
+ class_addmethod(pmenu_class, (t_method)pmenu_set,
+ gensym("set"),A_GIMME,0);
+
+ class_addsymbol(pmenu_class, (t_method)pmenu_symbol);
+
+ class_addfloat(pmenu_class, (t_method)pmenu_float);
+
+
+
+ //class_setwidget(pmenu_class,&pmenu_widgetbehavior);
+
+ //class_setsavefn(pmenu_class,&pmenu_save);
+
+
+ post("pmenu v0.01 by tof");
+}
+
+
diff --git a/test/pmenu_w.h b/test/pmenu_w.h
new file mode 100644
index 0000000..713b47e
--- /dev/null
+++ b/test/pmenu_w.h
@@ -0,0 +1,331 @@
+
+#define UPDATE 0
+#define CREATE 1
+#define DESTROY 2
+/*
+static int pmenu_w_is_visible(t_pmenu* x) {
+
+ return ( x->x_glist != NULL);
+
+}
+
+static void pmenu_w_text(t_pmenu* x, t_symbol* s) {
+
+ sys_vgui(".x%x.c itemconfigure %xLABEL -text {%s} \n",
+ glist_getcanvas(x->x_glist), x, s->s_name);
+
+
+}
+*/
+
+static void pmenu_w_activate(t_pmenu* x){
+ //sys_vgui("$%xw activate %i\n", x,x->current_selection);
+ sys_vgui("set %xradio %i\n",x,x->current_selection);
+}
+
+
+static void pmenu_w_clear(t_pmenu* x){
+ sys_vgui("$%xw delete 0 end \n", x);
+ sys_vgui("set %xradio %i\n",x,-1);
+}
+
+static void pmenu_w_additem(t_pmenu* x, t_symbol *label, int i) {
+
+ sys_vgui("$%xw add radiobutton -label \"%s\" -command {select%x \"%d\"} -variable %xradio -value %d \n",
+ x, label->s_name, x, i,x,i);
+}
+
+static void pmenu_w_apply_colors(t_pmenu* x) {
+
+ sys_vgui("$%xw configure -background \"%s\" -foreground \"%s\" -activeforeground \"%s\" -activebackground \"%s\" -selectcolor \"%s\"\n", x,
+ x->bg_color->s_name,x->fg_color->s_name,x->fg_color->s_name,x->hi_color->s_name,x->fg_color->s_name);
+
+ /*
+ 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 pmenu_w_draw_inlets(t_pmenu *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 pmenu_w_menu(t_pmenu *x, int draw)
+{
+ DEBUG(post("menu start");)
+
+ if ( draw == CREATE ) {
+ //x->created = 1;
+ // Create menu
+ //sys_vgui("set %xw .x%x.c.s%x ; menubutton $%xw -justify left
+ // Create a variable to store a pointer to the menu, create the menu, create a variable to store the selected item
+ sys_vgui("set %xw .%x ; menu $%xw -relief solid -tearoff 0; set %xradio 0 \n",x,x,x);
+ int i;
+ for(i=0 ; i<x->x_num_options ; i++)
+ {
+ // Add menu itmes
+ pmenu_w_additem(x,x->x_options[i],i);
+ }
+ } else if ( draw == DESTROY) {
+ //x->created = 0;
+ sys_vgui("destroy $%xw \n",x);
+ }
+
+ //DEBUG(post("id: .x%x.c.s%x", glist, x);)
+ DEBUG(post("menu end");)
+}
+
+
+
+
+/*
+static void pmenu_w_draw(t_pmenu *x, t_glist *glist, int draw)
+{
+
+ int xpos = text_xpix(&x->x_obj,glist);
+ int ypos = text_ypix(&x->x_obj,glist);
+ t_canvas* canvas = glist_getcanvas(glist);
+ //t_canvas *canvas=glist_getcanvas(glist);
+ DEBUG(post("drawme start");)
+
+ DEBUG(post("drawme %d",draw);)
+ if (draw==CREATE) {
+ // Base
+
+ sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xR -fill \"%s\" -outline \"%s\" \n",
+ canvas, xpos, ypos ,
+ xpos + x->x_width, ypos + x->x_height,
+ x,x->bg_color->s_name,x->co_color->s_name);
+
+ // Text
+ sys_vgui(".x%x.c create text %d %d -text {%s} -anchor w -fill \"%s\" -tags %xLABEL -width %i \n" ,
+ canvas, xpos+2, ypos+x->x_height/2,
+ "",x->fg_color->s_name, x, x->x_width-2,x->x_height -2);
+ //-font {{%s} -%d %s}
+ //x->x_gui.x_font, x->x_gui.x_fontsize, sys_fontweight
+ } else if (draw==UPDATE) {
+ // Base
+ sys_vgui(".x%x.c coords %xR %d %d %d %d\n",
+ canvas, x,
+ xpos, ypos ,
+ xpos + x->x_width, ypos + x->x_height );
+ // Text
+ sys_vgui(".x%x.c coords %xLABEL %d %d\n",
+ canvas, x, xpos+2,ypos+x->x_height/2);
+ } else {
+ // Base
+ sys_vgui(".x%x.c delete %xR\n",canvas,x);
+ // Text
+ sys_vgui(".x%x.c delete %xLABEL\n", canvas, x);
+
+ DEBUG(post("erase done");)
+ }
+
+ DEBUG(post("drawme end");)
+}
+*/
+/*
+static void pmenu_w_resize(t_pmenu* x) {
+
+ //sys_vgui(".x%x.c itemconfigure %xS -width %i -height %i \n", x->x_glist, x,x->x_width-1,x->x_height-1);
+
+
+ pmenu_w_draw(x,x->x_glist,UPDATE);
+ canvas_fixlinesfor(x->x_glist,(t_text*) x);
+}
+*/
+/*
+static void pmenu_w_getrect(t_gobj *z, t_glist *owner,
+ int *xp1, int *yp1, int *xp2, int *yp2)
+{
+ // DEBUG(post("getrect start");)
+
+ int width, height;
+ t_pmenu* s = (t_pmenu*)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 ;
+ *yp2 = text_ypix(&s->x_obj, owner) + height ;
+
+ // DEBUG(post("getrect end");)
+}
+
+
+static void pmenu_w_displace(t_gobj *z, t_glist *glist,
+ int dx, int dy)
+{
+ t_pmenu *x = (t_pmenu *)z;
+ DEBUG(post("displace start");)
+ x->x_obj.te_xpix += dx;
+ x->x_obj.te_ypix += dy;
+
+ //pmenu_w_draw_handle(x,glist,UPDATE);
+ //pmenu_w_draw_inlets(x, glist, UPDATE, 1,1);
+ pmenu_w_draw(x, glist, UPDATE);
+ canvas_fixlinesfor(glist_getcanvas(glist),(t_text*) x);
+
+ DEBUG(post("displace end");)
+}
+
+static void pmenu_w_select(t_gobj *z, t_glist *glist, int state)
+{
+ DEBUG(post("select start");)
+
+ t_pmenu *x = (t_pmenu *)z;
+
+
+ //sys_vgui(".x%x.c itemconfigure %xhandle -fill %s\n", glist,
+ //x, (state? "blue" : x->fg_color->s_name));
+
+ if (state) {
+ //pmenu_w_draw_handle(x,glist,CREATE);
+ pmenu_w_draw_inlets(x, glist, CREATE, 1,1);
+ //pmenu_w_disable(x,1);
+ }
+ else {
+ //pmenu_w_disable(x,0);
+ //pmenu_w_draw_handle(x,glist,DESTROY);
+ pmenu_w_draw_inlets(x,glist,DESTROY,1,1);
+
+ }
+
+
+ DEBUG(post("select end");)
+}
+
+
+// Standard delete function
+static void pmenu_w_delete(t_gobj *z, t_glist *glist)
+{
+
+ canvas_deletelinesfor(glist, (t_text *)z);
+
+}
+
+// Standard create function
+static void pmenu_w_vis(t_gobj *z, t_glist *glist, int vis)
+{
+ t_pmenu* x = (t_pmenu*)z;
+ t_rtext *y;
+ DEBUG(post("vis start");)
+ DEBUG(post("vis: %d",vis);)
+ if (vis) {
+ x->x_glist = glist;
+
+ pmenu_w_draw(x, glist, CREATE);
+ } else {
+ x->x_glist = NULL;
+ //if ( x->created ) pmenu_w_menu(x, glist,DESTROY);
+ pmenu_w_draw(x, glist, DESTROY);
+ }
+
+ DEBUG(post("vis end");)
+}
+*/
+
+static void pmenu_w_pop(t_pmenu *x) {
+
+ if (x->x_num_options > 0) {
+ //if ( x->created == 0 ) pmenu_w_menu(x, glist, CREATE);
+ if ( x->current_selection != -1 ) {
+ sys_vgui("tk_popup $%xw [winfo pointerx .] [winfo pointery .] %i\n",x,x->current_selection);
+ } else {
+ sys_vgui("tk_popup $%xw [winfo pointerx .] [winfo pointery .] 1\n",x);
+ }
+ }
+
+}
+
+/*
+static int pmenu_w_click(t_pmenu *x, struct _glist *glist,
+ int xpos, int ypos, int shift, int alt, int dbl, int doit) {
+
+ DEBUG(post("x: %i,y: %i,shift: %i, alt: %i, dbl: %i, doit: %i",xpos,ypos,shift,alt,dbl,doit);)
+
+ //if (doit) sys_vgui("tk_popup $%xw %i %i \n",x,100,100);
+
+ if (doit && x->x_num_options > 0) {
+ //if ( x->created == 0 ) pmenu_w_menu(x, glist, CREATE);
+ if ( x->current_selection != -1 ) {
+ sys_vgui("tk_popup $%xw [winfo pointerx .] [winfo pointery .] %i\n",x,x->current_selection);
+ } else {
+ sys_vgui("tk_popup $%xw [winfo pointerx .] [winfo pointery .] \n",x);
+ }
+ }
+ return (1);
+}
+*/
+
+/*
+t_widgetbehavior pmenu_widgetbehavior = {
+ w_getrectfn: pmenu_w_getrect,
+ w_displacefn: pmenu_w_displace,
+ w_selectfn: pmenu_w_select,
+ w_activatefn: NULL,
+ w_deletefn: pmenu_w_delete,
+ w_visfn: pmenu_w_vis,
+ //w_clickfn: NULL,
+ w_clickfn: (t_clickfn)pmenu_w_click,
+};
+*/