Re: [fltk.general] FLTK-1.3 group button menus in wrong place whe rearranged

2013-04-08 Thread Albrecht Schlosser
On 08.04.2013 11:58, Albrecht Schlosser wrote:

> There are two ways to overcome this:

.. at least ..

> (1) I recommend not to use Fl_Pack, ...
>
> (2) I don't recommend this one, but it should give you a clue
> ...

(3) You might also recalculate the button positions in your
callbacks/functions to modify the group, i.e. clearto() and/or
onMenu(), but you would have to do it in the same way as Fl_Pack
would do it later in its draw() method. This way, you'd have the
popup() work depending on the new positions, as you expect. The
point why I don't recommend this either is because you'd have to
*know* how Fl_Pack calculates the positions. However, this is not
trivial, but could work with your simple buttons. But if you do
this anyway, why not create an own group class? You could also
overwrite the resize() method and rearrange your buttons while
the window/group is being resized. Then you would be able to call
resize() after you rearranged the group's buttons, and that's it.
I like this more than recalculating positions in draw(), because
(a) it's less overhead, and (b) you avoid the problems you see
in your program.

So I still recommend (1).

Here's a small amendment to my previous posting. I wrote:

 > Here the menu pops up, but Fl_Pack still "knows" of the old
 > button position(s), hence the unexpected position.

In fact, Fl_Pack is not involved here. It's the button widget
that still "knows" its old position, because Fl_Pack didn't
rearrange the children yet.

Albrecht

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


Re: [fltk.general] FLTK-1.3 group button menus in wrong place whe rearranged

2013-04-08 Thread MacArthur, Ian (Selex ES, UK)
Oh! I was mid-reply, and I see Albrecht has already said most of what I was 
going to say...


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

As Albrecht said, the way Fl_Pack behaves in practice is probably not what you 
want for your use case.

I have to confess I don't much care for Fl_Pack in general; every time I tried 
to use it, I ended up in difficulties.
Albrecht suggests deriving your own container from Fl_Group - this is probably 
the best bet; looks like more work initially but in practice it will be easier 
as it gives you so much more control over the way your widgets are positioned, 
sized and redrawn...

Albrecht also suggests a workaround based on timers. I think this might work 
out pretty well, though I'd consider having my own derived Fl_Pack (or similar 
container widget) that, in its derived draw() method, sets a flag to tell 
whether the draw has actually been enacted (and hence the sizes properly 
recalculated) and have that flag cleared down by the callback that triggers the 
timer.

The timer can then "poll" until it sees that the widget has been drawn (the 
flag is re-set) and thence that the sizes ought to be correct, for popping up 
the menus now...

Well, something like that...




Also, some entirely spurious critique of the example code, for no other reason 
than I was part way through rewriting it anyway...

> static Fl_Font  LFONT = FL_BOLD;

Would be better to say:

static Fl_Font  LFONT = FL_HELVETICA | FL_BOLD;

Which is actually the same thing, but makes it explicit: It is (kinda) just 
chance that FL_BOLD on its own works (since FL_HELV... == 0). Really it is 
meant as a "modifier", not a name in its own right!

> 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; // not really needed
> };



> //cc
> 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)]; // not needed, and maybe too small 
> anyway?

  char _cstr[16]; // use a stack automatic temp instead, cheaper than 
calling new
> sprintf(_cstr, "%i", id);
> // label(_cstr);
  copy_label(_cstr); // use copy_label so the widget manages the label 
string for you




> //cc
> Sbut::~Sbut ()
> {
> // delete _cstr;
> }
> 
> //***
> int main (int argc, char **argv)
> {



> WIN->end();
> //WIN->resizable(G1);
// With a pack, it may be that...
  WIN->resizable(WIN); // might work out better...

// Passing argc, argv to show() ensures that fltk picks up 
// the system default settings... Useful on some host systems.
> WIN->show(argc, argv);
> return Fl::run();
> }


Selex ES Ltd
Registered Office: Sigma House, Christopher Martin Road, Basildon, Essex SS14 
3EL
A company registered in England & Wales.  Company no. 02426132

This email and any attachments are confidential to the intended
recipient and may also be privileged. If you are not the intended
recipient please delete it from your system and notify the sender.
You should not copy it or use it for any purpose nor disclose or
distribute its contents to any other person.


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


Re: [fltk.general] FLTK-1.3 group button menus in wrong place whe rearranged

2013-04-08 Thread Albrecht Schlosser
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
features.


Albrecht

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


Re: [fltk.general] FLTK-1.3 group button menus in wrong place whe rearranged

2013-04-08 Thread Duncan Gibson
marty moore  wrote:
> 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.

You could always set up a series of different panes in Fl_Wizard
where each pane has a status label and the set of buttons that
are relevant in the current program context, and switch between
panes as part of a button callback.

D.

This message and any attachments are intended for the use of the addressee or 
addressees only. The unauthorised disclosure, use, dissemination or copying 
(either in whole or in part) of its content is not permitted. If you received 
this message in error, please notify the sender and delete it from your system. 
Emails can be altered and their integrity cannot be guaranteed by the sender.

Please consider the environment before printing this email.

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


[fltk.general] FLTK-1.3 group button menus in wrong place whe rearranged

2013-04-07 Thread marty moore
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 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 

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;
};

//
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();
}

//
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();
}

}

//m
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}
};


//cc
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; jlabelsize(FSIZE);
mi->labelfont(LFONT);
mi->labelcolor(LFG);
mi = mi->next();
}
}
}

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

//hH
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();
}

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

//***
int main ()
{
Sbut