There's at least three ways to do this, in order of preference:
#1 Make a class, make the three widgets members of the class,
and refer to them in your callback, passing the class's own pointer
as the 'userdata'.
#2 Use globals for all the widgets, and refer to them in your callback
so that you don't have to pass them.
#3 Make a struct, putting all three widget pointers in the struct,
and make the 'user data' a pointer to the struct, so that the
callback can access all three widgets in the struct.
See this video tutorial on FLTK which shows #2 first, then #1 second:
http://seriss.com/people/erco/fltk-videos/tutorial-fltk-hello.html
I think that will help you.
Note that the Fl_Widget passed as the first argument will always be
the widget invoked by the callback only. No matter how you cast it,
that's what it will be. And the second argument, the void *userdata
will be whatever was set as the userdata when you set the callback
for that widget.
andrei_c wrote:
> Hello everyone!
>
> As the title implies I am having a bit of a problem regarding how to
> "comunicate" between multiple widgets.
>
> As an example, I wanted to make a program that has one button and some other
> widgets who's properties should change when the button is pressed.
> As you know, to do this I must make a special callback function which must be
> called inside the "callback" method of a widget.Something like this:
>
> button_1.callback(button_cb,some_data)
>
> The button_cb is a function I have to make myself and in every tutorial it
> seems to be like:
> void button_cb(Fl_Widget *w, void *v)
>
> Those to input parameters, *w and *v can then be used to "obtain" the widgets
> you need by casting.What this theoretically means is that i can only
> comunicate between maximum 3 widgets:
> -the widget that triggers the callback
> -and other 2 widgets via casting from *w and *v
>
> So I made a simple program whit 4 widgets: a Fl_Button and 3 Fl_Input.I chose
> 4 widgets because 3 seems to be the maximum so I wanted more than 3.This is
> my program:
>
> Program 1
>
> #include <FL/Fl.H>
> #include <FL/Fl_Double_Window.H>
> #include <FL/Fl_Button.H>
> #include <FL/Fl_Input.H>
>
> void button_cb(Fl_Widget *w, void *v) // the callback function
> {
> Fl_Input *my_input1 = (Fl_Input*) w;
> Fl_Input *my_input2 = (Fl_Input*) v;
> Fl_Input *my_input3 = (Fl_Input*) v; // I used the *v pointer 2 times
>
> my_input1->value("BBB"); // the value should change to "BBB"
> }
>
> /*********************************************************************************/
> int main()
> {
> Fl_Double_Window my_win(300,180, "Multiple widgets");
> my_win.begin();
>
> Fl_Input input_1(60,20,200,30,"Input 1");
> input_1.value("AAA");
>
> Fl_Input input_2(60,60,200,30,"Input 2");
> input_2.value("BBB");
>
> Fl_Input input_3(60,100,200,30,"Input 2");
> input_3.value("CCC");
>
> Fl_Button button_1(60,140,100,30,"Change");
> button_1.callback(button_cb,&input_1);
>
> my_win.end();
> my_win.show();
>
> return Fl::run();
>
> }
> /*********************************************************************************/
>
> As you can see, I've still passed only 2 arguments to button_1 callback
> method,, because that's the maximum, but I thougth about solving this problem
> later, after all I want more than one widget to be changed.But untill the I
> thougth I should just compile this program and see what happens.The program
> does compile, the fact that I've casted more than once isn't an error.But
> when I press the button the program crashes.
> Where could I have gone wrong???
> After all, I casted Fl_Widget *w to an Fl_Input *my_input_1, to "get" the
> first widget.And even better I've passed the input_1 object created in main()
> to the callback function as well, so the callback would about what widget I
> was talking about.And even better, eve if I've casted void *v 2 times for the
> other 2 widgets, I never tried to change their values, I just casted, that's
> all.But still the program crashes.
> In my naivety I thougth that maybe Fl_Input does not have a value() method so
> I thougth about changing it to something I'm sure Fl_Input has,like
> color().So I changed the program a little:
>
> Program 2 , modified callback function
>
> void button_cb(Fl_Widget *w, void *v) // the callback function
> {
> Fl_Input *my_input1 = (Fl_Input*) w;
> Fl_Input *my_input2 = (Fl_Input*) v;
> Fl_Input *my_input3 = (Fl_Input*) v; // I used the *v pointer 2 times
>
> my_input1->color(0); // this should make the color of the input black
> }
>
> As you can see I've only changed one line of code inside the button_cb
> function.The program does compile again, but when I press the "Change" button
> guess who's color changes into black???It's the button's color which changes
> into black!!!!Incredible!!!!
> Even if I casted the Fl_Widget *w to Fl_Input, even if in the callback of
> button_1 I've specifically placed an Fl_Input like:
> button_1.callback(button_cb,&input_1);
> it's the button's color which changes.Why???
> This made me understand that in the:
> void button_cb(Fl_Widget *w, void *v)
> function, the first input, Fl_Widget *w is reserved for the calling object,
> no matter how you cast it.In this case the calling object was the button_1
> via it's callback function.So kind of an indirect call, because it doesn't
> call the button_cb() directly.
>
> ******Anyway, is this true??That he first parameter is reserved somehow for
> the calling object???And if so, why???????******
>
> Even better, not only the first parameter Fl_Widget *w seems to be reserved,
> but also the second one which doesn't mind casting to other widget types.Like
> this:
>
> Program 3 , the second parameter seems to be reserved two
>
> #include <FL/Fl.H>
> #include <FL/Fl_Double_Window.H>
> #include <FL/Fl_Button.H>
> #include <FL/Fl_Input.H>
> #include <FL/Fl_Value_Slider.H>
>
> void button_cb(Fl_Widget *w, void *v)
> {
> Fl_Button *my_button = (Fl_Button*) w; // este defapt butonul
> Fl_Input *my_input1 = (Fl_Input*) v;
> Fl_Value_Slider *my_input2 = (Fl_Value_Slider*) v;
>
> my_button->color(100000);
> my_input1->value("BBB");
> my_input2->color(10); // the color should change
> }
>
> /*********************************************************************************/
> int main()
> {
> Fl_Double_Window my_win(300,150, "Multiple widgets");
> my_win.begin();
>
> Fl_Input input_1(60,20,200,30,"Input 1");
> input_1.value("AAA");
>
> Fl_Input input_2(60,60,200,30,"Input 2");
> input_2.value("BBB");
>
> Fl_Button button_1(60,100,100,30,"Change");
> button_1.callback(button_cb,&input_1);
>
> my_win.end();
> my_win.show();
>
> return Fl::run();
>
> }
> /*********************************************************************************/
>
> As you can see above, now I'm casting the second parameter, void *v to
> different types of widgets, an Fl_Input and an Fl_Value_Slider.But in the
> callback function of button_1 I pass an Fl_Input as in:
> button_1.callback(button_cb,&input_1);
>
> The program above does compile, and even better when I press the button, not
> only that the value of input_1 changes but also it's color, even if in
> button_cb i do this:
> //
> Fl_Value_Slider *my_input2 = (Fl_Value_Slider*) v;
> //
> my_input2->color(10); // the color should change
>
> I try to change the color of an Fl_Value_Slider, not an Fl_Input, but still
> the color of input_1 changes, and that's an Fl_Input.
> I suspect that this is because both are Fl_Widgets and thy both have a color
> method, but I'm not shore.
> Please note that this second problem might be related to my poor
> understanding of C++ as well, I am not an expert :)
>
> ********Anyway the question is:
> Is it true that in the button_cb function the second parameter is reserved
> for what you put in the callback method of the object???*******
> Like this:
>
> void button_cb(Fl_Widget *w, void *v)
> button_1.callback(button_cb,&input_1);
>
> I mean that the *v should be reserved for input_1
>
> Thank for at least reading this long post.As you can see my questions ended
> up being about something else than multiple widget callbacks, but the
> questions turned out of the need to do multiple widgets callback :)
>
> P.S:
> This message was supposed to be larger , but my computer is slow so I will
> split it up into 2 or more posts.
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk