Post by Greg Ercolano//hhhhhhhhhhhhhhhhhhhhhhhhhH
int Sbut::handle ( int event )
{
if ( event == FL_PUSH )
{
cout << "Sbut handle 1: PUSH " << endl;
do_callback();
return 1;
}
return 0;
}
Also, unrelated, the above bit of code should be repaired.
As it is, the button's own handle() method is being completely eclipsed.
Fl_Button::handle(event); should really be called in there somewhere
to allow the button's mechanics to operate.
int Sbut::handle ( int event )
{
if ( event == FL_PUSH )
cout << "Sbut handle 1: PUSH " << endl;
return(Fl_Button::handle(event);
}
..and the button's own code will handle the do_callback() on PUSH.
Hi again,
I've been playing with your suggestions and,, comments on my example program.
Here's what I've found:
1. The resetting of all the buttons (Sbut::resetAll) works fine, but only if 'sb->popup()'
isn't called at the end of the 'onMenu' function. If I call 'sb->popup()', then the menus aren't quite in the right place, although you can see half the button that owns the menu. The 'fl_add_timeout' method is the only thing that seemed to work, so the reviesed example program (beloe) has both methods. The automatic popping up of the next menu is important for my application's design.
2. This program still uses Fl_Pack. I had originally tried Fl_Pack to see what it would do. When changed over to Fl_Group, buttons lower in the window don't respond properly. It seems like the clicked button and above are the only responding buttons. I quit playing with Fl_Group since I couldn't remedy the unpredictable buttons.
3. I've removed the 'Sbut::handle' method since all it did in this program was to tell me that the buttons weren't responding. Thanks for the edit. In my application, though, I need to do some stuff before 'popup()' is called, so I carried it over from my app.
I'm applying what I've learned to my application.
Thanks again for your efforts.
Marty
revised example program:
****************************
#include <iostream>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <FL/Fl.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Menu_Button.H>
#include <FL/Fl_Menu_Item.H>
#include <FL/Fl_Pack.H>
#include <FL/Fl_Window.H>
using std::cout;
using std::endl;
using std::string;
class Grp;
static Grp* BG;
static Fl_Window* WIN;
static int idx = 0;
static Fl_Color LBG = FL_DARK_BLUE;
static Fl_Color LFG = FL_WHITE;
static Fl_Color LSC = FL_BLUE;;
static Fl_Color LTC = FL_WHITE;
static Fl_Font LFONT = (FL_HELVETICA | FL_BOLD);
static Fl_Fontsize FSIZE = 30;
static int LSPC = 2;
enum eop { DEL=-1, ADD=1 };
class Sbut : public Fl_Menu_Button
{
public:
Sbut (int i);
static void pop_on_timeout(void *v);
int _lw, _lh;
};
//**************************************
class Grp : public Fl_Pack
{
public:
Grp (int x, int y, int w, int h);
~Grp() {}
void clearTo ( int idx );
void print (string s);
void resetAll ();
};
//cccccccccccccccccccccccccccccccccccccc
Grp::Grp (int x, int y, int w, int h)
: Fl_Pack(x,y,w,h)
{
cout << "Grp 0:" << endl;
}
//ffffffffffffffffffffffffffffffffffffff
void Grp::print (string s)
{
int lw, lh;
cout << "Grp print: " << s << endl;
for ( int i=0; i<children(); i++ )
{
child(i)->measure_label(lw,lh);
cout << i << ": " << child(i)->x() << " "
<< child(i)->y() << " "
<< child(i)->w() << " "
<< child(i)->h()
<< "| "
<< lw << ": " << lh
<< " " << 6*lw << ": " << 2*lh
<< endl;
}
}
//ffffffffffffffffffffffffffffffffffffff
void Grp::resetAll ()
{
cout << "resetAll 0:" << endl;
int ih = child(0)->h();
int hh = ih;
int ww = 0;
int yy = -ih;
int xx = 0;
for ( int i=0; i<children(); i++ )
{
if ( child(i)->w() > ww )
ww = child(i)->w();
}
for ( int i=0; i<children(); i++ )
{
if ( BG->child(i)->w() > ww )
ww = BG->child(i)->w();
yy += ih + LSPC;
child(i)->resize( LSPC, yy, ww, hh);
}
resize( 0, 0, ww, yy);
WIN->resize( 0, 0, ww+2*LSPC, yy+ih+LSPC);
print("resetAll 99:");
}
//ffffffffffffffffffffffffffff
void Grp::clearTo ( int idx )
{
cout << "Grp clearto " << idx << ": ";
Fl_Widget* w;
int last = BG->children()-1;
if ( last > idx )
cout << " removing ";
{
// remove last to idx
for ( int i=last; i>-1; i-- )
{
if ( i != idx )
{
cout << i << " ";
w = BG->child(i);
BG->remove(w);
delete w;
}
}
}
WIN->redraw();
cout << endl;
}
//static void pop_on_timeout(void *v)
void Sbut::pop_on_timeout(void *v)
{
Sbut* sb = (Sbut*)v;
// WIN->redraw();
cout << "pop_on_timeout: popping menu" << endl;
sb->popup();
}
//hhhhhhhhhhhhhhhhhhhhhhhhhhhh
void onMenu (Fl_Widget* w, void* v)
{
eop op = (eop)fl_intptr_t(v);
Sbut* sb;
if ( op == ADD )
{
cout << "onMenu: add" << endl;
sb = new Sbut(idx);
BG->add(sb);
idx++;
BG->resetAll();
}
else if ( op == DEL )
{
cout << "onMenu 2: deleting" << endl;
int i = BG->find(w);
BG->clearTo(i);
sb = (Sbut*)BG->child(0);
BG->resetAll();
}
// sb->popup();
Fl::add_timeout(0.2, Sbut::pop_on_timeout,
(void*)sb);
}
//mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
Fl_Menu_Item xMenu[] = {
{"add button to end, and popup menu", 0, onMenu, (void*)ADD},
{"delete other buttons, and popup menu", 0, onMenu, (void*)DEL},
{0}
};
//cccccccccccccccccccccccccc
Sbut::Sbut (int id )
: Fl_Menu_Button(0, 0, 5*FSIZE, 2*FSIZE)
{
char _cstr[16];
sprintf(_cstr, "%i", id);
copy_label(_cstr);
// cout << "label = " << label() << endl;
color( LBG, LSC);
labelcolor(LFG);
labelfont(LFONT);
labelsize(FSIZE);
measure_label(_lw, _lh);
size(5*_lw, int(1.3*_lh));
menu(xMenu);
if ( menu() )
{
Fl_Menu_Item* mi; // non-const pointer
mi = (Fl_Menu_Item*)menu();
int sz = mi->size();
for ( int j=0; j<sz; j++ )
{
// cout << "set: " << j << endl;
color(LBG, LSC);
mi->labelsize(FSIZE);
mi->labelfont(LFONT);
mi->labelcolor(LFG);
mi = mi->next();
}
}
}
//***********************
int main (int argc, char **argv)
{
Sbut* sb;
WIN = new Fl_Window(0, 0, 200, 300);
BG = new Grp(0, 0, 150, 150);
for ( int i=0; i<5; i++ )
{
sb = new Sbut(i);
idx++;
}
BG->end();
WIN->end();
BG->resetAll();
WIN->show(argc, argv);
return Fl::run();
}