Hi all,
I'm playing around with dynamic buttons in a group. I'm using FLTK-1.3, 
gcc-4.4.5, emacs 23, on a debian 6.5(64bit) system.

An example program, which demonstrates the problem,is included below.

What's supposed to happen:
1. click on a button, and a menu pops up with "add" and "delete" options.
2. click on "delete", and all other buttons disappear, and another menu for the 
clicked button appears(same options).
3. click on "add", and another button is added, and a menu pops up for the new 
button.

What happens:
1. When the first button is clicked, and the "delete" option is selected, the 
other buttons disappear, but the menu is where the clicked button used to be, 
not where the button is actually located.
2. If the "add" option is selected from the popped up menu, the menu is located 
on top of the new button.
3. Continue selecting "add", and the all of the menus appear over the first 
added button.
4. If "escape" is pressed, or the button is clicked again to cancel the menu, 
the buttons and menus seem to act properly again.

So it appears that when a previous button in the group is removed, the button's 
menu position doesn't get updated.

Is there any way to update the menu position, other than manually with
   popup(x,y....) or pulldown(x,y,w,h....)

I've tried init_sizes() and sizes(), to no avail.
I've alse tried using activate to no avail.

I've been playing around with this because I want to create a set of buttons 
that change to indicate where the user is in the program, instead of using a 
status bar. Maybe a little odd, but sounded interesting.

I'd appreciate any ideas.
Marty

the example code:
#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;

Fl_Pack* G1;
Fl_Window* WIN;

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_BOLD;
static Fl_Fontsize FSIZE = 30;
static int LSPC = 5;

enum eop { DEL=-1, ADD=1 };

class Sbut  : public Fl_Menu_Button
{
public:
    Sbut (int i);
    ~Sbut ();

    static void onButton ( Fl_Widget* w, void* v);
    int handle ( int event );
    int i() { return _i; }

    int _i;
    char* _cstr;
};

//ffffffffffffffffffffffffffff
void clearTo ( int idx )
{
    cout << "clearto " << idx << ": ";
    Fl_Widget* w;

    int last = G1->children()-1;
    if ( last > idx )
        cout << " removing ";
    {
        // remove last to idx
        for ( int i=last; i>-1; i-- )
        {
            if ( i != idx )
            {
                cout <<  i << " ";
                w = G1->child(i);
                G1->remove(w);
                delete w;
            }
        }
    }
    WIN->redraw();
    cout << endl;
//    cout << "popping menu" << endl;
//    Sbut* sb = (Sbut*)G1->child(0);
//    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);
        G1->add(sb);
        idx++;
        WIN->redraw();
        cout << "onMenu 1: popping menu" << endl;
        sb->show();
        sb->popup();
    }
    else if ( op == DEL )
    {
        cout << "onMenu 2: deleting" << endl;
        int i = G1->find(w);
        clearTo(i);
        WIN->redraw();
        cout << "onMenu 3: poping menu" << endl;
        sb = (Sbut*)G1->child(0);
        sb->popup();
    }

}

//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, 100, 50)
{
//    cout << "Sbut(s) 0: " << id << endl;
    _i = idx;
    callback(onButton);
    _cstr = new char[sizeof(int)];
    sprintf(_cstr, "%i", id);
    label(_cstr);
//    cout << "label = " << label() << endl;
    color( LBG, LSC);
    labelcolor(LFG);
    labelfont(LFONT);
    labelsize(FSIZE);
    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();
        }
    }
}

//hhhhhhhhhhhhhhhhhhhhhhhhhH
int Sbut::handle ( int event )
{
    if ( event == FL_PUSH )
    {
        cout << "Sbut handle 1: PUSH " << endl;
        do_callback();
        return 1;
    }
    return 0;
}

//hhhhhhhhhhhhhhhhhhhhhhhhhH
void Sbut::onButton ( Fl_Widget* w, void* v)
{
    int i = G1->find(w);
    cout << "Sbut onButton 0: " << i << endl;
    Sbut* sb = (Sbut*)w;
    sb->popup();
}

//cccccccccccccccccccccccccc
Sbut::~Sbut ()
{
    delete _cstr;
}

//***********************
int main ()
{
    Sbut* sb;
    WIN = new Fl_Window(0, 0, 200, 300);
    G1 = new Fl_Pack(0, 0, 150, 150);
    G1->begin();
    for ( int i=0; i<5; i++ )
    {
        sb = new Sbut(i);
        idx++;
    }
    G1->end();
    WIN->end();
//    WIN->resizable(G1);
    WIN->show();
    return Fl::run();
}


_______________________________________________
fltk mailing list
fltk@easysw.com
http://lists.easysw.com/mailman/listinfo/fltk

Reply via email to