Order of variables in FLUID

40 visualizzazioni
Passa al primo messaggio da leggere

anmol....@gmail.com

da leggere,
6 ott 2020, 11:25:1606/10/20
a fltk.general
I've run into a problem multiple times. Essentially I have a double_window with derived tab and in the tab there are groups with widgets.
The order of definition of groups decides the display order of tabs.
So I need to have a particular order there.

As a result I have issues with static defined widgets defined after they are first called.

For instance a widget in Tab 1 may need to initialize or obtain values from a widget in Tab 2.

Is there a way to specify the order of static widget declaration? Or a way to tell the compiler to parse all the statics first and then the code?

This can be avoided with globals - but I would rather not extern all my widgets.

Greg Ercolano

da leggere,
6 ott 2020, 12:27:4806/10/20
a fltkg...@googlegroups.com
On 2020-10-06 08:25, anmol....@gmail.com wrote:
> I've run into a problem multiple times. Essentially I have a double_window with derived tab and in the tab there are groups with widgets.
> The order of definition of groups decides the display order of tabs.
> So I need to have a particular order there.
>
> As a result I have issues with static defined widgets defined after they are first called.
>
> For instance a widget in Tab 1 may need to initialize or obtain values from a widget in Tab 2.
>
> Is there a way to specify the order of static widget declaration? Or a way to tell the compiler to parse all the statics first and then the code?

Since each tab is usually a group, let's call these 'tab group widgets',
where each contains the layout for a particular tab.

Normally I'd say change the design so that any dependence between the
"tab group widgets" is done AFTER they're created. This way they can
be instanced in whatever order makes sense to create the tabs (from left
to right), and then /after/ they're all created, call a method in each
tab group widget that lets interact.

I assume the interaction is perhaps widget positioning (?), where
maybe one "tab widget group"'s contents defines where the other's
positions should be, so create a default layout in fluid for each
"tab group widget", and then the above described method just uses
position() or resize() to lock the widgets to one another.

You can create each "tab group widget" in fluid as a separate New -> Window,
and change the class type (in properties; C++ -> Class:) to Fl_Group,
and then layout each tab group widget's contents the way you want,
then use New -> Code -> Group in the tab widget's constructor that
creates the instances of each tab group widget (using "new YourWidget(..)")
and calls the above described method.

anmol....@gmail.com

da leggere,
6 ott 2020, 13:58:1806/10/20
a fltk.general
Actually I face a problem from the callbacks. I have Tabs  and then Group 1 and Group 2, 3, 4.
Now inside Tabs I detect a click to Group 4 where there is Fl_Browser. Once I detect that
Group 4 is selected, I copy the selections to a queue which is implemented inside Fl_Browser.

Since Tabs comes before Group 4 in the heirarchy (in order Group 1,2,3,4)
I am unable to access Group 1 ->  Fl_Output in the Tabs callback.
 
So the " dependence between the
"tab group widgets" is done AFTER they're created"
but I still get the undeclared identifier error.

Am I missing something here ?

Greg Ercolano

da leggere,
6 ott 2020, 14:31:3506/10/20
a fltkg...@googlegroups.com
On 2020-10-06 10:58, anmol....@gmail.com wrote:
> Actually I face a problem from the callbacks. I have Tabs  and then Group 1 and Group 2, 3, 4.
> Now inside Tabs I detect a click to Group 4 where there is Fl_Browser.

OK, I assume you've set Fl_Tabs::callback() to invoke your own callback.

Are you using globals for groups 1,2,3,4?

If so, then your tabs callback should be able to access groups 1,2,3,4
by those variables, and be able to access their methods with whatever
API you provide.

> So the " dependence between the "tab group widgets" is done AFTER they're created"
> but I still get the undeclared identifier error.

It's not clear to me why that would be.

When you create the group instances and name them, those variables should
be set by the time your callback is invoked, as the tabs widget all four
"tab group widgets" would have been initialized.

> Am I missing something here ?

Need more info.

Perhaps show a quick fluid layout of a window -> tabs -> two groups
and an Fl_Input/Fl_Output in one or the other, and show your callback
code that tries to do the work.

Another approach is text messaging, where widgets send messages from
one to the other, but that's only if you're doing a large application.
If this is small, you can surely just do it with callbacks.

Greg Ercolano

da leggere,
6 ott 2020, 14:47:2806/10/20
a fltkg...@googlegroups.com
On 2020-10-06 10:58, anmol....@gmail.com wrote:
> Actually I face a problem from the callbacks. I have Tabs  and then Group 1 and Group 2, 3, 4.
> Now inside Tabs I detect a click to Group 4 where there is Fl_Browser. Once I detect that
> Group 4 is selected, I copy the selections to a queue which is implemented inside Fl_Browser.

I'm trying to make a fluid mockup of your situation, creating two groups and putting
an Fl_Browser in one, which presumably is loaded with text when that group is selected.

Question: Where do 'the selections' come from?
Is that a separate browser widget outside the tabs widget? i.e.

___________________________________________________________________
| | Tabs Widget |
| Source Browser | _______ _______ |
| _________________ | / Grp 1 \/ Grp 2 \_______________________ |
| | | | | _______________ | |
| | | | | | Queue browser | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | (A) | | | | (B) | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | |_______________| | |
| | | | | | |
| |_________________| | |________________________________________| |
|_____________________|____________________________________________|

And the user makes selections in the source browser, and then clicks
on the "Grp 2" tab to trigger a callback that should then copy selections
from Source Browser (A) over to Queue Browser (B)?

Greg Ercolano

da leggere,
6 ott 2020, 14:49:4906/10/20
a fltkg...@googlegroups.com

    Reposting my last message (below) with preformatted text, as I'm not sure what Google Groups interface will do with that ascii art.


On 2020-10-06 11:47, Greg Ercolano wrote:

anmol....@gmail.com

da leggere,
7 ott 2020, 06:45:1407/10/20
a fltk.general
Hi Greg. I took the morning to do lots more reading to understand what you were referring to in terms of solutions - I have to save data from different tabs, and one widget in one tab can set the output of another widget.
When the user clicks on Group 4, it must summarize in text form all the choices made in Group 1-3.

If a widget A sets the value of widget B - is the callback for widget B invoked ? Or can it be invoked ?
In this case, I do not need to worry about which widget sets the value of B, I can save the current value into a class using widget B callback. And this will always be consistent.

The browser is part of Group 4.
___________________________________________________________________
|                     |  Tabs Widget                               |
| Source Browser      |  _______  _______                          |
|  _________________  | / Grp 1 \/ Grp 4 \_______________________  |
| |                 | | |       | _______________                | |
| |                 | | |       || Queue browser |               | |
| |                 | | |       ||               |               | |
| |                 | | |       ||               |               | |
| |                 | | |       ||               |               | |
| |      (A)        | | |       ||      (B)      |               | |
| |                 | | |       ||               |               | |
| |                 | | |       ||               |               | |
| |                 | | |       ||               |               | |
| |                 | | |       ||_______________|               | |
| |                 | | |       |                                | |
| |_________________| | |________________________________________| |
|_____________________|____________________________________________|

    

Greg Ercolano

da leggere,
7 ott 2020, 11:36:4007/10/20
a fltkg...@googlegroups.com
On 2020-10-07 03:45, anmol....@gmail.com wrote:
> Hi Greg. I took the morning to do lots more reading to understand what you were referring to in terms of solutions - I have to save data from different tabs, and one widget in one tab can set the output of another widget.
> When the user clicks on Group 4, it must summarize in text form all the choices made in Group 1-3.

OK, so assuming you have a single callback for the tab widget which is fired
when someone clicks the group4 tab, it can access the data from the other 3 groups
and apply it to group 4's browser.

Set names for the different widgets so they are each assigned variables, and access
the variables to read from/write to the widgets to update their data.

To assign variable names to e.g. the browser widget, open the properties for that
widget, and under C++ -> Name: type in a variable name to use for it. That will be
assigned by fluid's code that sets up the widget, and those names can be accessed
from your tab callback. Be sure the pulldown to the right of the above descibed
Name: prompt is set to "global", so the variable is defined as a global.

> If a widget A sets the value of widget B - is the callback for widget B invoked ? Or can it be invoked ?

For this the only callback you'd need is the one you have already for the tab,
and just have that callback directly access the widgets to read/write them.

You could get more complicated and make the tab group widgets modular subclasses
that don't use globals. In that case, make an API in each class that lets you
access the data within each group and return it as an array of strings in the
format you want, and then your tab callback would invoke your subclass methods
to accumulate the array of strings, and then pass that array to the group 4
widget that would apply those strings in whatever way to the browser.
Presumably each subclass would have a way to save out its widget's settings
into text, and if need be, each could also have a way to apply those strings
to the widgets, updating them based on the array's contents. This is basically
"messaging", just without the formal structure of a centralized messaging system.

anmol....@gmail.com

da leggere,
8 ott 2020, 03:20:1908/10/20
a fltk.general
This is the easiest method. I was trying to avoid having globals but if I name them right, everything works.

duncan

da leggere,
8 ott 2020, 03:30:5208/10/20
a fltk.general
 Be sure the pulldown to the right of the above descibed
Name: prompt is set to "global", so the variable is defined as a global.
 
This is the easiest method. I was trying to avoid having globals but if I name them right, everything works.

You can always use fluid as a quick design tool, with globals, and then refactor
into classes where those globals become member variables with accessors.
It takes a bit more effort but ...

D

Greg Ercolano

da leggere,
8 ott 2020, 05:19:1108/10/20
a fltkg...@googlegroups.com
Here's a fluid file that uses subclasses for grp1 and grp4, defining the
source and destination widgets as public member variables that the tab
callback manipulates. (Can easily be modified to use accessors, but I wanted
to keep the example simple)

When you run the app, you see the two groups, 1 and 4 as tabs.
Whatever you type into the multiline input in group 1, when you click
the group 4 tab, it gets copied into the browser first.

Source is an Fl_Input widget called 'input', destination is an Fl_Multiline_Browser
called 'browser', and these are members in custom classes named MyGroup1 and MyGroup4
respectively.

The instances of the groups are globals, G_grp1 and G_grp4, so the tab callback
looks like this:

static void cb_G_tabs(Fl_Tabs*, void*) {
printf("Tab callback:\n");
Fl_Widget *w = G_tabs->value();
if ( !w ) return;
printf(" Clicked '%s'\n", w->label());
if ( strcmp(w->label(), "Group 4") == 0 ) {
printf(" Copying contents of grp1 input -> grp4 browser.\n");
G_grp4->browser->clear();
char *copy = strdup(G_grp1->input->value()); // make a copy we can change
char *s = copy;
while ( *s ) {
char *ss = strchr(s,'\n');
if ( ss ) *ss = 0;
G_grp4->browser->add(s);
if ( !ss ) break;
s = ss + 1;
}
free((void*)copy); // free the copy we made
}
}

Note there's a lot of fluid features being taken advantage of here:

> Defining subclasses of gui widgets in fluid as separate windows
> Custom code in the subclass to initialize the input and browser
> Custom code in main to force the tab group to show group1 (not group4)
> Using Fl_Tabs with dummy groups that are re-classed to use the above defined subclasses
> The callback code defined within the Fl_Tabs properties editor, "C++ -> Callback:"

Changing the group1 or group2 subclass GUI layouts affect the contents of the tab groups
when the app is running.

tabgroups.fl
Rispondi a tutti
Rispondi all'autore
Inoltra
0 nuovi messaggi