On 08.04.2013 01:27, marty moore wrote:

> 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....)

Your problem lies buried in Fl_Pack. This is not designed to be
updated dynamically the way you try to do it, or at least this
doesn't work as expected. The reason why this is so is because
Fl_Pack rearranges its children only when it is draw(), but this
doesn't happen when you might expect it to do.

In your code, this part is called in a callback:

>      else if ( op == DEL )
>      {
>       cout << "onMenu 2: deleting" << endl;
>       int i = G1->find(w);
>       clearTo(i);
>       WIN->redraw();

Here you ask the window to be drawn, but this doesn't happen
until the event loop is reached again, either by returning
from the callback or ... (see below).

>       cout << "onMenu 3: poping menu" << endl;
>       sb = (Sbut*)G1->child(0);
>       sb->popup();

Here the menu pops up, but Fl_Pack still "knows" of the old
button position(s), hence the unexpected position. But this
popup() call also includes running the event loop again, until
the menu will be closed. Now you will see the new button
position(s), but the menu stays at the "old" position.

There are two ways to overcome this:

(1) I recommend not to use Fl_Pack, but instead calculate the
new button positions yourself (use a class derived from Fl_Group),
and everything ought to work as expected if you calculate the
positions before calling popup(). Note that calling init_sizes()
has nothing to do with Fl_Pack's and/or Fl_Groups position
calculations, unless you resize() the group or window. Hence it
would be useful to call init_sizes() after re-positioning the
buttons in the group.

(2) I don't recommend this one, but it should give you a clue
whether I'm right with my assumption. ;-) Instead of calling
popup() in the callback, as you did above, start a timer with
a short time, say 0.3 seconds, and popup() the menu in this
timer callback. If you did this, then the window's draw() would
happen before the timer callback runs, and therefore Fl_Pack's
draw() method would have adjusted the positions already. Although
this might look as the easier part, I don't consider this good
style, and if you extend your program later, Fl_Pack will maybe
not be the widget/group you want to use because of its restricted


fltk mailing list

Reply via email to